From 867d96ff0a099f8ff26bc3edc61e88f5251ba7be Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:12:38 -0600 Subject: [PATCH 001/168] Add IControllable to creative energy emitter (#2248) --- .../storage/MetaTileEntityCreativeEnergy.java | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java index 7b76fa8e57f..ec6afb97341 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java @@ -2,7 +2,9 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IControllable; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.ILaserContainer; import gregtech.api.gui.GuiTextures; @@ -35,6 +37,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -42,9 +45,10 @@ import static gregtech.api.GTValues.MAX; import static gregtech.api.GTValues.V; +import static gregtech.api.capability.GregtechDataCodes.UPDATE_ACTIVE; import static gregtech.api.capability.GregtechDataCodes.UPDATE_IO_SPEED; -public class MetaTileEntityCreativeEnergy extends MetaTileEntity implements ILaserContainer { +public class MetaTileEntityCreativeEnergy extends MetaTileEntity implements ILaserContainer, IControllable { private long voltage = 0; private int amps = 1; @@ -89,6 +93,8 @@ public T getCapability(Capability capability, EnumFacing side) { return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(this); } else if (capability == GregtechTileCapabilities.CAPABILITY_LASER) { return GregtechTileCapabilities.CAPABILITY_LASER.cast(this); + } else if (capability == GregtechTileCapabilities.CAPABILITY_CONTROLLABLE) { + return GregtechTileCapabilities.CAPABILITY_CONTROLLABLE.cast(this); } else { return super.getCapability(capability, side); } @@ -126,7 +132,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(7, 110, () -> "Energy I/O per sec: " + this.lastEnergyIOPerSec, 0x232323); - builder.widget(new CycleButtonWidget(7, 139, 77, 20, () -> active, value -> active = value, + builder.widget(new CycleButtonWidget(7, 139, 77, 20, () -> active, this::setActive, "gregtech.creative.activity.off", "gregtech.creative.activity.on")); builder.widget(new CycleButtonWidget(85, 139, 77, 20, () -> source, value -> { source = value; @@ -144,6 +150,13 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return builder.build(getHolder(), entityPlayer); } + public void setActive(boolean active) { + this.active = active; + if (!getWorld().isRemote) { + writeCustomData(GregtechDataCodes.UPDATE_ACTIVE, buf -> buf.writeBoolean(active)); + } + } + @Override public void addToolUsages(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { tooltip.add(I18n.format("gregtech.tool_action.screwdriver.access_covers")); @@ -297,13 +310,27 @@ public void setIOSpeed(long energyIOPerSec) { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_IO_SPEED) { this.lastEnergyIOPerSec = buf.readLong(); + } else if (dataId == UPDATE_ACTIVE) { + this.active = buf.readBoolean(); } } + @Override + public void writeInitialSyncData(@NotNull PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(active); + } + + @Override + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.active = buf.readBoolean(); + } + public static Function getTextFieldValidator() { return val -> { if (val.isEmpty()) { @@ -321,4 +348,14 @@ public static Function getTextFieldValidator() { return val; }; } + + @Override + public boolean isWorkingEnabled() { + return active; + } + + @Override + public void setWorkingEnabled(boolean isWorkingAllowed) { + setActive(isWorkingAllowed); + } } From a36667f43f384423fc546872e50d7df63b92cd9d Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:14:38 -0500 Subject: [PATCH 002/168] fix using client only method for harder bed recipe names (#2253) --- .../java/gregtech/loaders/recipe/VanillaOverrideRecipes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/loaders/recipe/VanillaOverrideRecipes.java b/src/main/java/gregtech/loaders/recipe/VanillaOverrideRecipes.java index b057a3e3b0d..dbf9b401b47 100644 --- a/src/main/java/gregtech/loaders/recipe/VanillaOverrideRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/VanillaOverrideRecipes.java @@ -649,7 +649,7 @@ private static void miscRecipes() { } private static void addBedRecipe(int meta) { - String colorName = EnumDyeColor.byMetadata(meta).getDyeColorName(); + String colorName = EnumDyeColor.byMetadata(meta).getName(); if ("silver".equals(colorName)) { // thank you mojang colorName = "light_gray"; From 012b56be055e36bc946caf3fea26a9ffee0f53f9 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:31:49 -0700 Subject: [PATCH 003/168] Fix plasma temps all being the default temp (#2256) --- src/main/java/gregtech/api/fluids/FluidBuilder.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index 88bf5fa5519..757369b75ae 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -427,7 +427,12 @@ private void determineTemperature(@Nullable Material material) { yield ROOM_TEMPERATURE; } case GAS -> ROOM_TEMPERATURE; - case PLASMA -> BASE_PLASMA_TEMPERATURE; + case PLASMA -> { + if (material.hasFluid()) { + yield BASE_PLASMA_TEMPERATURE + material.getFluid().getTemperature(); + } + yield BASE_PLASMA_TEMPERATURE; + } }; } else { temperature = property.getBlastTemperature() + switch (state) { From c48d179bdeeb36f5af2a321c8b7c12dccb6701a7 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:57:52 -0600 Subject: [PATCH 004/168] Update build script version to 1701739812 (#2257) Co-authored-by: DStrand1 --- build.gradle | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 62f21b90cb9..5e4447c6c45 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1701481996 +//version: 1701739812 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -222,6 +222,16 @@ if (enableSpotless.toBoolean()) { //noinspection GroovyAssignabilityCheck eclipse('4.19.0').configFile(formatFile) } + kotlin { + target 'src/*/kotlin/**/*.kt' + + toggleOffOn() + ktfmt('0.39') + + trimTrailingWhitespace() + indentWithSpaces(4) + endWithNewline() + } scala { target 'src/*/scala/**/*.scala' scalafmt('3.7.1') From 7247805629c1bdb3e028f8a06bd58d269eabaea4 Mon Sep 17 00:00:00 2001 From: Tictim Date: Thu, 7 Dec 2023 11:52:27 +0900 Subject: [PATCH 005/168] Re-implement walking speed bonus (#2251) --- .../api/block/IWalkingSpeedBonus.java | 8 ++ .../api/block/VariantActiveBlock.java | 2 +- .../java/gregtech/api/block/VariantBlock.java | 30 ++---- .../java/gregtech/api/util/BlockUtility.java | 49 ++++++++++ .../java/gregtech/common/EventHandlers.java | 98 ++++++++++++++++++- .../gregtech/common/blocks/BlockAsphalt.java | 10 -- .../common/blocks/BlockBatteryPart.java | 2 +- .../gregtech/common/blocks/BlockColored.java | 24 ++--- .../common/blocks/BlockSteamCasing.java | 2 +- .../gregtech/common/blocks/BlockWireCoil.java | 2 +- .../gregtech/common/blocks/MetaBlocks.java | 51 +++++++++- .../common/blocks/StoneVariantBlock.java | 48 +++------ src/main/java/gregtech/core/CoreModule.java | 23 ++++- 13 files changed, 246 insertions(+), 103 deletions(-) diff --git a/src/main/java/gregtech/api/block/IWalkingSpeedBonus.java b/src/main/java/gregtech/api/block/IWalkingSpeedBonus.java index 508b5c9e416..4b932286cdb 100644 --- a/src/main/java/gregtech/api/block/IWalkingSpeedBonus.java +++ b/src/main/java/gregtech/api/block/IWalkingSpeedBonus.java @@ -3,6 +3,14 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; +import org.jetbrains.annotations.ApiStatus; + +/** + * @deprecated use {@link gregtech.api.util.BlockUtility#setWalkingSpeedBonus(IBlockState, double)} + */ +@SuppressWarnings("DeprecatedIsStillUsed") +@Deprecated +@ApiStatus.ScheduledForRemoval(inVersion = "2.9") public interface IWalkingSpeedBonus { default double getWalkingSpeedBonus() { diff --git a/src/main/java/gregtech/api/block/VariantActiveBlock.java b/src/main/java/gregtech/api/block/VariantActiveBlock.java index e2fd7864005..4818c4a933a 100644 --- a/src/main/java/gregtech/api/block/VariantActiveBlock.java +++ b/src/main/java/gregtech/api/block/VariantActiveBlock.java @@ -120,7 +120,7 @@ public int getMetaFromState(IBlockState state) { @NotNull @Override protected BlockStateContainer createBlockState() { - Class enumClass = getActualTypeParameter(getClass(), VariantActiveBlock.class, 0); + Class enumClass = getActualTypeParameter(getClass(), VariantActiveBlock.class); this.VARIANT = PropertyEnum.create("variant", enumClass); this.VALUES = enumClass.getEnumConstants(); return new ExtendedBlockState(this, new IProperty[] { VARIANT, ACTIVE_DEPRECATED }, diff --git a/src/main/java/gregtech/api/block/VariantBlock.java b/src/main/java/gregtech/api/block/VariantBlock.java index 25b2ebbe389..5b0310263ef 100644 --- a/src/main/java/gregtech/api/block/VariantBlock.java +++ b/src/main/java/gregtech/api/block/VariantBlock.java @@ -11,11 +11,9 @@ import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.Entity; import net.minecraft.item.ItemStack; import net.minecraft.util.IStringSerializable; import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -28,11 +26,13 @@ import java.util.Collections; import java.util.List; +@SuppressWarnings("deprecation") public class VariantBlock & IStringSerializable> extends Block implements IWalkingSpeedBonus { protected PropertyEnum VARIANT; protected T[] VALUES; + @SuppressWarnings("DataFlowIssue") public VariantBlock(Material materialIn) { super(materialIn); if (VALUES.length > 0 && VALUES[0] instanceof IStateHarvestLevel) { @@ -77,7 +77,7 @@ public ItemStack getItemVariant(T variant, int amount) { @NotNull @Override protected BlockStateContainer createBlockState() { - Class enumClass = getActualTypeParameter(getClass(), VariantBlock.class, 0); + Class enumClass = getActualTypeParameter(getClass(), VariantBlock.class); this.VARIANT = PropertyEnum.create("variant", enumClass); this.VALUES = enumClass.getEnumConstants(); return new BlockStateContainer(this, VARIANT); @@ -85,7 +85,7 @@ protected BlockStateContainer createBlockState() { @Override @SideOnly(Side.CLIENT) - public void addInformation(@NotNull ItemStack stack, @Nullable World player, List tooltip, + public void addInformation(@NotNull ItemStack stack, @Nullable World player, @NotNull List tooltip, @NotNull ITooltipFlag advanced) { // tier less tooltip like: tile.turbine_casing.tooltip String unlocalizedVariantTooltip = getTranslationKey() + ".tooltip"; @@ -114,27 +114,9 @@ public int getMetaFromState(IBlockState state) { return state.getValue(VARIANT).ordinal(); } - @Override - public void onEntityWalk(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull Entity entityIn) { - // Short circuit if there is no bonus speed - if (getWalkingSpeedBonus() == 1.0D) { - return; - } - - IBlockState below = entityIn.getEntityWorld() - .getBlockState(new BlockPos(entityIn.posX, entityIn.posY - (1 / 16D), entityIn.posZ)); - if (checkApplicableBlocks(below)) { - if (bonusSpeedCondition(entityIn)) { - entityIn.motionX *= getWalkingSpeedBonus(); - entityIn.motionZ *= getWalkingSpeedBonus(); - } - } - } - // magic is here @SuppressWarnings("unchecked") - protected static Class getActualTypeParameter(Class thisClass, Class declaringClass, - int index) { + protected static Class getActualTypeParameter(Class thisClass, Class declaringClass) { Type type = thisClass.getGenericSuperclass(); while (!(type instanceof ParameterizedType) || ((ParameterizedType) type).getRawType() != declaringClass) { @@ -144,6 +126,6 @@ protected static Class getActualTypeParameter(Class thisC type = ((Class) type).getGenericSuperclass(); } } - return (Class) ((ParameterizedType) type).getActualTypeArguments()[index]; + return (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; } } diff --git a/src/main/java/gregtech/api/util/BlockUtility.java b/src/main/java/gregtech/api/util/BlockUtility.java index e84e996b92d..77b816da15a 100644 --- a/src/main/java/gregtech/api/util/BlockUtility.java +++ b/src/main/java/gregtech/api/util/BlockUtility.java @@ -2,15 +2,45 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import net.minecraft.util.NonNullList; +import it.unimi.dsi.fastutil.objects.Object2DoubleMap; +import it.unimi.dsi.fastutil.objects.Object2DoubleMaps; +import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap; import org.jetbrains.annotations.NotNull; +import java.util.Objects; +import java.util.UUID; + public class BlockUtility { private static final BlockWrapper WRAPPER = new BlockWrapper(); + private static final Object2DoubleMap walkingSpeedBonusInternal = new Object2DoubleOpenHashMap<>(); + /** + * View-only collection of block states that give speed bonus when walking over it. The bonus value is a percentage + * value that gets added to the player speed; for example, a bonus value of {@link 0.25} will add 25% of extra speed + * to the player. + */ + public static final Object2DoubleMap WALKING_SPEED_BONUS = Object2DoubleMaps.unmodifiable( + walkingSpeedBonusInternal); + + /** + * UUID of the walking speed bonus attribute applied to players. + */ + public static final UUID WALKING_SPEED_UUID = UUID.fromString("415ac431-8339-4150-965c-e673a8a328be"); + + /** + * Walking speed bonus applied to asphalt and concrete blocks. + */ + public static final double ASPHALT_WALKING_SPEED_BONUS = 0.6; + /** + * Walking speed bonus applied to studs. + */ + public static final double STUDS_WALKING_SPEED_BONUS = 0.25; + private static class BlockWrapper extends Block { public BlockWrapper() { @@ -31,4 +61,23 @@ public static void startCaptureDrops() { public static NonNullList stopCaptureDrops() { return WRAPPER.captureDrops(false); } + + /** + * Set walking speed bonus for the block state. The bonus value is a percentage value that gets added to the player + * speed; for example, a bonus value of {@link 0.25} will add 25% of extra speed to the player. + * + * @param state block state + * @param amount amount of walking speed bonus + */ + public static void setWalkingSpeedBonus(@NotNull IBlockState state, double amount) { + Objects.requireNonNull(state, "state == null"); + if (!Double.isFinite(amount)) { + throw new IllegalArgumentException("Haha funny i put NaN and Infinity in your API method haha no"); + } + if (amount == 0) { + walkingSpeedBonusInternal.remove(state); + } else { + walkingSpeedBonusInternal.put(state, amount); + } + } } diff --git a/src/main/java/gregtech/common/EventHandlers.java b/src/main/java/gregtech/common/EventHandlers.java index a25b6b99716..da32dd83ca5 100644 --- a/src/main/java/gregtech/common/EventHandlers.java +++ b/src/main/java/gregtech/common/EventHandlers.java @@ -1,6 +1,7 @@ package gregtech.common; import gregtech.api.GTValues; +import gregtech.api.block.IWalkingSpeedBonus; import gregtech.api.items.armor.ArmorMetaItem; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.items.toolitem.ToolHelper; @@ -8,6 +9,7 @@ import gregtech.api.pipenet.longdist.LongDistanceNetwork; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.unification.material.Materials; +import gregtech.api.util.BlockUtility; import gregtech.api.util.CapesRegistry; import gregtech.api.util.GTUtility; import gregtech.api.util.VirtualTankRegistry; @@ -18,8 +20,12 @@ import gregtech.common.items.behaviors.ToggleEnergyConsumerBehavior; import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityCentralMonitor; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityOtherPlayerMP; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; @@ -31,7 +37,9 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.EnumDifficulty; +import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.event.entity.living.EnderTeleportEvent; import net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent; @@ -148,8 +156,7 @@ public static void onDestroySpeed(net.minecraftforge.event.entity.player.PlayerE @SubscribeEvent(priority = EventPriority.LOW) public static void onEntityLivingFallEvent(LivingFallEvent event) { - if (event.getEntity() instanceof EntityPlayerMP) { - EntityPlayerMP player = (EntityPlayerMP) event.getEntity(); + if (event.getEntity() instanceof EntityPlayerMP player) { ItemStack armor = player.getItemStackFromSlot(EntityEquipmentSlot.FEET); ItemStack jet = player.getItemStackFromSlot(EntityEquipmentSlot.CHEST); @@ -206,9 +213,94 @@ public static void onLivingEquipmentChangeEvent(LivingEquipmentChangeEvent event } } + @SuppressWarnings({ "ConstantValue", "deprecation" }) @SubscribeEvent - @SideOnly(Side.CLIENT) public static void onPlayerTick(TickEvent.PlayerTickEvent event) { + EntityPlayer player = event.player; + if (event.phase == TickEvent.Phase.START && !player.world.isRemote) { + IAttributeInstance movementSpeed = player.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); + if (movementSpeed == null) return; + AttributeModifier modifier = movementSpeed.getModifier(BlockUtility.WALKING_SPEED_UUID); + + double speedBonus; + if (!player.onGround || player.isInWater() || player.isSneaking()) { + speedBonus = 0; + } else { + IBlockState state = player.world.getBlockState(new BlockPos( + player.posX, player.getEntityBoundingBox().minY - 1, player.posZ)); + speedBonus = BlockUtility.WALKING_SPEED_BONUS.getDouble(state); + // { remove this bit while removing IWalkingSpeedBonus + if (speedBonus == 0 && + state.getBlock() instanceof IWalkingSpeedBonus walkingSpeedBonus && + walkingSpeedBonus.getWalkingSpeedBonus() != 1 && + walkingSpeedBonus.bonusSpeedCondition(player) && + walkingSpeedBonus.checkApplicableBlocks(state)) { + speedBonus = walkingSpeedBonus.getWalkingSpeedBonus() - 1; + } + // } + } + if (modifier != null) { + if (speedBonus == modifier.getAmount()) return; + else movementSpeed.removeModifier(BlockUtility.WALKING_SPEED_UUID); + } else { + if (speedBonus == 0) return; + } + if (speedBonus != 0) { + movementSpeed.applyModifier(new AttributeModifier(BlockUtility.WALKING_SPEED_UUID, + "Walking Speed Bonus", speedBonus, 2)); + } + } + } + + @SuppressWarnings({ "lossy-conversions", "ConstantValue" }) + @SubscribeEvent + @SideOnly(Side.CLIENT) + public static void onFOVUpdate(FOVUpdateEvent event) { // this event SUCKS + EntityPlayer player = event.getEntity(); + IAttributeInstance movementSpeed = player.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); + if (movementSpeed == null || movementSpeed.getModifier(BlockUtility.WALKING_SPEED_UUID) == null) return; + + float originalFov = player.capabilities.isFlying ? 1.1f : 1.0f; + originalFov *= (movementSpeed.getAttributeValue() / player.capabilities.getWalkSpeed() + 1) / 2; + + if (player.capabilities.getWalkSpeed() == 0 || Float.isNaN(originalFov) || Float.isInfinite(originalFov)) { + return; + } + + float newFov = player.capabilities.isFlying ? 1.1f : 1.0f; + newFov *= (computeValueWithoutWalkingSpeed(movementSpeed) / player.capabilities.getWalkSpeed() + 1) / 2; + + event.setNewfov(newFov / originalFov * event.getNewfov()); + } + + /** + * Computes walking speed without boost from {@link BlockUtility#WALKING_SPEED_BONUS}. Skipping parent check stuff + * because movement speed attribute does not have any parent modifier. + */ + private static double computeValueWithoutWalkingSpeed(IAttributeInstance attrib) { + double base = attrib.getBaseValue(); + + for (AttributeModifier m : attrib.getModifiersByOperation(0)) { + base += m.getAmount(); + } + + double applied = base; + + for (AttributeModifier m : attrib.getModifiersByOperation(1)) { + applied += base * m.getAmount(); + } + + for (AttributeModifier m : attrib.getModifiersByOperation(2)) { + if (m.getID() == BlockUtility.WALKING_SPEED_UUID) continue; + applied *= 1 + m.getAmount(); + } + + return attrib.getAttribute().clampValue(applied); + } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public static void onPlayerTickClient(TickEvent.PlayerTickEvent event) { if (event.phase == TickEvent.Phase.START && !event.player.isSpectator() && !(event.player instanceof EntityOtherPlayerMP) && !(event.player instanceof FakePlayer)) { ItemStack feetEquip = event.player.getItemStackFromSlot(EntityEquipmentSlot.FEET); diff --git a/src/main/java/gregtech/common/blocks/BlockAsphalt.java b/src/main/java/gregtech/common/blocks/BlockAsphalt.java index 2b27036768e..281e47c76b8 100644 --- a/src/main/java/gregtech/common/blocks/BlockAsphalt.java +++ b/src/main/java/gregtech/common/blocks/BlockAsphalt.java @@ -32,16 +32,6 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces return false; } - @Override - public double getWalkingSpeedBonus() { - return 1.6D; - } - - @Override - public boolean checkApplicableBlocks(IBlockState state) { - return state == getState(BlockType.ASPHALT); - } - public enum BlockType implements IStringSerializable, IStateHarvestLevel { ASPHALT("asphalt", 0); diff --git a/src/main/java/gregtech/common/blocks/BlockBatteryPart.java b/src/main/java/gregtech/common/blocks/BlockBatteryPart.java index e89734051b1..1f8548a56af 100644 --- a/src/main/java/gregtech/common/blocks/BlockBatteryPart.java +++ b/src/main/java/gregtech/common/blocks/BlockBatteryPart.java @@ -41,7 +41,7 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces } @Override - public void addInformation(@NotNull ItemStack stack, @Nullable World world, List tooltip, + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, @NotNull ITooltipFlag advanced) { super.addInformation(stack, world, tooltip, advanced); diff --git a/src/main/java/gregtech/common/blocks/BlockColored.java b/src/main/java/gregtech/common/blocks/BlockColored.java index 9f84069c345..db2f2049e9f 100644 --- a/src/main/java/gregtech/common/blocks/BlockColored.java +++ b/src/main/java/gregtech/common/blocks/BlockColored.java @@ -12,12 +12,9 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -public class BlockColored extends VariantBlock { +import org.jetbrains.annotations.NotNull; - public BlockColored() { - this(net.minecraft.block.material.Material.IRON, "block_colored", 2.0f, 5.0f, SoundType.METAL, - EnumDyeColor.WHITE); - } +public class BlockColored extends VariantBlock { public BlockColored(Material material, String translationKey, float hardness, float resistance, SoundType soundType, EnumDyeColor defaultColor) { @@ -30,23 +27,14 @@ public BlockColored(Material material, String translationKey, float hardness, fl } @Override - public boolean canCreatureSpawn(IBlockState state, IBlockAccess world, BlockPos pos, - EntityLiving.SpawnPlacementType type) { + public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos, + @NotNull EntityLiving.SpawnPlacementType type) { return false; } @Override - public double getWalkingSpeedBonus() { - return 1.25; - } - - @Override - public boolean checkApplicableBlocks(IBlockState state) { - return this == MetaBlocks.STUDS; - } - - @Override - public boolean recolorBlock(World world, BlockPos pos, EnumFacing side, EnumDyeColor color) { + public boolean recolorBlock(World world, @NotNull BlockPos pos, @NotNull EnumFacing side, + @NotNull EnumDyeColor color) { if (world.getBlockState(pos) != getState(color)) { world.setBlockState(pos, getState(color)); return true; diff --git a/src/main/java/gregtech/common/blocks/BlockSteamCasing.java b/src/main/java/gregtech/common/blocks/BlockSteamCasing.java index c3e1fdc251b..58188233370 100644 --- a/src/main/java/gregtech/common/blocks/BlockSteamCasing.java +++ b/src/main/java/gregtech/common/blocks/BlockSteamCasing.java @@ -39,7 +39,7 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces } @Override - public void addInformation(@NotNull ItemStack stack, @Nullable World player, List tooltip, + public void addInformation(@NotNull ItemStack stack, @Nullable World player, @NotNull List tooltip, @NotNull ITooltipFlag advanced) { int ordinal = getState(stack).ordinal(); if (ordinal < 2) { diff --git a/src/main/java/gregtech/common/blocks/BlockWireCoil.java b/src/main/java/gregtech/common/blocks/BlockWireCoil.java index 312e8e4d9c0..2496bba9267 100644 --- a/src/main/java/gregtech/common/blocks/BlockWireCoil.java +++ b/src/main/java/gregtech/common/blocks/BlockWireCoil.java @@ -49,7 +49,7 @@ public BlockRenderLayer getRenderLayer() { @Override @SideOnly(Side.CLIENT) - public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn, List lines, + public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn, @NotNull List lines, @NotNull ITooltipFlag tooltipFlag) { super.addInformation(itemStack, worldIn, lines, tooltipFlag); diff --git a/src/main/java/gregtech/common/blocks/MetaBlocks.java b/src/main/java/gregtech/common/blocks/MetaBlocks.java index 9395fdec645..ada71a669ac 100644 --- a/src/main/java/gregtech/common/blocks/MetaBlocks.java +++ b/src/main/java/gregtech/common/blocks/MetaBlocks.java @@ -11,17 +11,30 @@ import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.ore.StoneType; +import gregtech.api.util.BlockUtility; import gregtech.api.util.GTUtility; import gregtech.api.util.function.TriConsumer; import gregtech.client.model.SimpleStateMapper; import gregtech.client.model.modelfactories.BakedModelHandler; import gregtech.client.renderer.handler.MetaTileEntityRenderer; import gregtech.client.renderer.handler.MetaTileEntityTESR; -import gregtech.client.renderer.pipe.*; +import gregtech.client.renderer.pipe.CableRenderer; +import gregtech.client.renderer.pipe.FluidPipeRenderer; +import gregtech.client.renderer.pipe.ItemPipeRenderer; +import gregtech.client.renderer.pipe.LaserPipeRenderer; +import gregtech.client.renderer.pipe.OpticalPipeRenderer; import gregtech.common.ConfigHolder; import gregtech.common.blocks.foam.BlockFoam; import gregtech.common.blocks.foam.BlockPetrifiedFoam; -import gregtech.common.blocks.wood.*; +import gregtech.common.blocks.wood.BlockGregFence; +import gregtech.common.blocks.wood.BlockGregFenceGate; +import gregtech.common.blocks.wood.BlockGregPlanks; +import gregtech.common.blocks.wood.BlockGregWoodSlab; +import gregtech.common.blocks.wood.BlockRubberDoor; +import gregtech.common.blocks.wood.BlockRubberLeaves; +import gregtech.common.blocks.wood.BlockRubberLog; +import gregtech.common.blocks.wood.BlockRubberSapling; +import gregtech.common.blocks.wood.BlockWoodenDoor; import gregtech.common.items.MetaItems; import gregtech.common.pipelike.cable.BlockCable; import gregtech.common.pipelike.cable.Insulation; @@ -44,9 +57,15 @@ import gregtech.common.pipelike.optical.OpticalPipeType; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; -import net.minecraft.block.*; +import net.minecraft.block.Block; +import net.minecraft.block.BlockFence; +import net.minecraft.block.BlockFenceGate; +import net.minecraft.block.BlockLog; import net.minecraft.block.BlockLog.EnumAxis; +import net.minecraft.block.BlockSlab; import net.minecraft.block.BlockSlab.EnumBlockHalf; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.SoundType; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -73,8 +92,14 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -333,7 +358,8 @@ public static void init() { } /** - * Deterministically populates a category of MetaBlocks based on the unique registry ID of each qualifying Material. + * Deterministically populates a category of MetaBlocks based on the unique registry ID of each qualifying + * Material. * * @param materialPredicate a filter for determining if a Material qualifies for generation in the category. * @param blockGenerator a function which accepts a Materials set to pack into a MetaBlock, and the ordinal this @@ -601,6 +627,21 @@ public static void registerColors() { itemColors.registerItemColorHandler((s, i) -> ConfigHolder.client.defaultPaintingColor, HERMETIC_CASING); } + public static void registerWalkingSpeedBonus() { + for (IBlockState state : ASPHALT.getBlockState().getValidStates()) { + BlockUtility.setWalkingSpeedBonus(state, BlockUtility.ASPHALT_WALKING_SPEED_BONUS); + } + for (IBlockState state : STUDS.getBlockState().getValidStates()) { + BlockUtility.setWalkingSpeedBonus(state, BlockUtility.STUDS_WALKING_SPEED_BONUS); + } + for (StoneVariantBlock block : STONE_BLOCKS.values()) { + BlockUtility.setWalkingSpeedBonus(block.getState(StoneVariantBlock.StoneType.CONCRETE_DARK), + BlockUtility.ASPHALT_WALKING_SPEED_BONUS); + BlockUtility.setWalkingSpeedBonus(block.getState(StoneVariantBlock.StoneType.CONCRETE_LIGHT), + BlockUtility.ASPHALT_WALKING_SPEED_BONUS); + } + } + public static void registerOreDict() { OreDictUnifier.registerOre(new ItemStack(RUBBER_LEAVES), "treeLeaves"); OreDictUnifier.registerOre(new ItemStack(RUBBER_SAPLING), "treeSapling"); diff --git a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java index aac7f85a066..39194eea2a0 100644 --- a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java +++ b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java @@ -57,16 +57,6 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces return false; } - @Override - public double getWalkingSpeedBonus() { - return 1.6D; - } - - @Override - public boolean checkApplicableBlocks(@NotNull IBlockState state) { - return state == getState(StoneType.CONCRETE_DARK) || state == getState(StoneType.CONCRETE_LIGHT); - } - @Override protected boolean canSilkHarvest() { return this.stoneVariant == StoneVariant.SMOOTH; @@ -103,36 +93,20 @@ public String getName() { } public OrePrefix getOrePrefix() { - switch (this) { - case BLACK_GRANITE: - case RED_GRANITE: - case MARBLE: - case BASALT: - return OrePrefix.stone; - case CONCRETE_LIGHT: - case CONCRETE_DARK: - return OrePrefix.block; - default: - throw new IllegalStateException("Unreachable"); - } + return switch (this) { + case BLACK_GRANITE, RED_GRANITE, MARBLE, BASALT -> OrePrefix.stone; + case CONCRETE_LIGHT, CONCRETE_DARK -> OrePrefix.block; + }; } public Material getMaterial() { - switch (this) { - case BLACK_GRANITE: - return Materials.GraniteBlack; - case RED_GRANITE: - return Materials.GraniteRed; - case MARBLE: - return Materials.Marble; - case BASALT: - return Materials.Basalt; - case CONCRETE_LIGHT: - case CONCRETE_DARK: - return Materials.Concrete; - default: - throw new IllegalStateException("Unreachable"); - } + return switch (this) { + case BLACK_GRANITE -> Materials.GraniteBlack; + case RED_GRANITE -> Materials.GraniteRed; + case MARBLE -> Materials.Marble; + case BASALT -> Materials.Basalt; + case CONCRETE_LIGHT, CONCRETE_DARK -> Materials.Concrete; + }; } } diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 9c4d019cbae..c063eec5c15 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -48,7 +48,19 @@ import gregtech.core.advancement.internal.AdvancementManager; import gregtech.core.command.internal.CommandManager; import gregtech.core.network.internal.NetworkHandler; -import gregtech.core.network.packets.*; +import gregtech.core.network.packets.PacketBlockParticle; +import gregtech.core.network.packets.PacketClipboard; +import gregtech.core.network.packets.PacketClipboardNBTUpdate; +import gregtech.core.network.packets.PacketClipboardUIWidgetUpdate; +import gregtech.core.network.packets.PacketFluidVeinList; +import gregtech.core.network.packets.PacketKeysPressed; +import gregtech.core.network.packets.PacketNotifyCapeChange; +import gregtech.core.network.packets.PacketPluginSynced; +import gregtech.core.network.packets.PacketRecoverMTE; +import gregtech.core.network.packets.PacketReloadShaders; +import gregtech.core.network.packets.PacketUIClientAction; +import gregtech.core.network.packets.PacketUIOpen; +import gregtech.core.network.packets.PacketUIWidgetUpdate; import gregtech.core.sound.GTSoundEvents; import gregtech.core.sound.internal.SoundManager; import gregtech.core.unification.material.internal.MaterialRegistryManager; @@ -62,7 +74,13 @@ import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.LoaderException; import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.*; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.event.FMLServerStartedEvent; +import net.minecraftforge.fml.common.event.FMLServerStartingEvent; +import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import net.minecraftforge.fml.relauncher.Side; import org.apache.logging.log4j.LogManager; @@ -235,6 +253,7 @@ public void init(FMLInitializationEvent event) { /* End Cover Definition Registration */ DungeonLootLoader.init(); + MetaBlocks.registerWalkingSpeedBonus(); } @Override From ac46da291126c9535774224e2e696c25b97805e1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 6 Dec 2023 19:53:37 -0700 Subject: [PATCH 006/168] =?UTF-8?q?Rework=20Generators=202.0=20=E2=84=A2?= =?UTF-8?q?=EF=B8=8F=20=20(#2255)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/capability/impl/FuelRecipeLogic.java | 5 ++ .../SimpleGeneratorMetaTileEntity.java | 6 -- .../MetaTileEntityLargeCombustionEngine.java | 75 +++++++++++-------- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java index 1222349e113..64e305fb20a 100644 --- a/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java @@ -46,4 +46,9 @@ public int getParallelLimit() { // parallel is limited by voltage return Integer.MAX_VALUE; } + + @Override + public boolean isAllowOverclocking() { + return false; + } } diff --git a/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java index 3cac1149fcb..ee42074ecaa 100644 --- a/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java @@ -8,7 +8,6 @@ import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; import gregtech.api.gui.widgets.LabelWidget; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMap; @@ -111,11 +110,6 @@ protected ModularUI.Builder createGuiTemplate(EntityPlayer player) { builder.widget(new LabelWidget(6, 6, getMetaFullName())) .bindPlayerInventory(player.inventory, GuiTextures.SLOT, yOffset); - builder.widget(new CycleButtonWidget(7, 62 + yOffset, 18, 18, - workable.getAvailableOverclockingTiers(), workable::getOverclockTier, workable::setOverclockTier) - .setTooltipHoverString("gregtech.gui.overclock.description") - .setButtonTexture(GuiTextures.BUTTON_OVERCLOCK)); - return builder; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java index 64f7bedd107..4b298f25cd0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java @@ -344,7 +344,8 @@ public LargeCombustionEngineWorkableHandler(RecipeMapMultiblockController tileEn @Override protected void updateRecipeProgress() { if (canRecipeProgress && drawEnergy(recipeEUt, true)) { - + drainLubricant(); + drainOxygen(); drawEnergy(recipeEUt, false); // as recipe starts with progress on 1 this has to be > only not => to compensate for it @@ -354,11 +355,49 @@ protected void updateRecipeProgress() { } } + protected void checkOxygen() { + // check oxygen if present to boost production, and if the dynamo hatch supports it + if (combustionEngine.isBoostAllowed()) { + IMultipleTankHandler inputTank = combustionEngine.getInputFluidInventory(); + FluidStack boosterStack = isExtreme ? LIQUID_OXYGEN_STACK : OXYGEN_STACK; + isOxygenBoosted = boosterStack.isFluidStackIdentical(inputTank.drain(boosterStack, false)); + } + } + + protected void drainOxygen() { + if (isOxygenBoosted && totalContinuousRunningTime % 20 == 0) { + FluidStack boosterStack = isExtreme ? LIQUID_OXYGEN_STACK : OXYGEN_STACK; + combustionEngine.getInputFluidInventory().drain(boosterStack, true); + } + } + + protected boolean checkLubricant() { + // check lubricant and invalidate if it fails + IMultipleTankHandler inputTank = combustionEngine.getInputFluidInventory(); + if (LUBRICANT_STACK.isFluidStackIdentical(inputTank.drain(LUBRICANT_STACK, false))) { + return true; + } else { + invalidate(); + return false; + } + } + + protected void drainLubricant() { + if (totalContinuousRunningTime == 1 || totalContinuousRunningTime % 72 == 0) { + IMultipleTankHandler inputTank = combustionEngine.getInputFluidInventory(); + inputTank.drain(LUBRICANT_STACK, true); + } + } + @Override protected boolean shouldSearchForRecipes() { - return super.shouldSearchForRecipes() && - LUBRICANT_STACK.isFluidStackIdentical(((RecipeMapMultiblockController) metaTileEntity) - .getInputFluidInventory().drain(LUBRICANT_STACK, false)); + checkOxygen(); + return super.shouldSearchForRecipes() && checkLubricant(); + } + + @Override + protected boolean canProgressRecipe() { + return super.canProgressRecipe() && checkLubricant(); } @Override @@ -388,33 +427,5 @@ public void invalidate() { isOxygenBoosted = false; super.invalidate(); } - - @Override - protected boolean canProgressRecipe() { - // drain lubricant and invalidate if it fails - if (totalContinuousRunningTime == 1 || totalContinuousRunningTime % 72 == 0) { - IMultipleTankHandler inputTank = combustionEngine.getInputFluidInventory(); - if (LUBRICANT_STACK.isFluidStackIdentical(inputTank.drain(LUBRICANT_STACK, false))) { - inputTank.drain(LUBRICANT_STACK, true); - } else { - invalidate(); - return false; - } - } - - // drain oxygen if present to boost production, and if the dynamo hatch supports it - if (combustionEngine.isBoostAllowed() && - (totalContinuousRunningTime == 1 || totalContinuousRunningTime % 20 == 0)) { - IMultipleTankHandler inputTank = combustionEngine.getInputFluidInventory(); - FluidStack boosterStack = isExtreme ? LIQUID_OXYGEN_STACK : OXYGEN_STACK; - if (boosterStack.isFluidStackIdentical(inputTank.drain(boosterStack, false))) { - isOxygenBoosted = true; - inputTank.drain(boosterStack, true); - } else { - isOxygenBoosted = false; - } - } - return super.canProgressRecipe(); - } } } From 625c296272c7511a9c03c550feff6a44100dbab2 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 6 Dec 2023 21:06:22 -0600 Subject: [PATCH 007/168] Fix issues with ore byproduct page (#2262) --- .../java/gregtech/integration/jei/basic/OreByProduct.java | 3 ++- .../gregtech/integration/jei/basic/OreByProductCategory.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/integration/jei/basic/OreByProduct.java b/src/main/java/gregtech/integration/jei/basic/OreByProduct.java index 825747c51e6..fb1af11438b 100755 --- a/src/main/java/gregtech/integration/jei/basic/OreByProduct.java +++ b/src/main/java/gregtech/integration/jei/basic/OreByProduct.java @@ -9,6 +9,7 @@ import gregtech.api.unification.material.properties.OreProperty; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; +import gregtech.client.utils.TooltipHelper; import gregtech.common.metatileentities.MetaTileEntities; import net.minecraft.client.resources.I18n; @@ -296,7 +297,7 @@ public void addTooltip(int slotIndex, boolean input, Object ingredient, List 0); } From d298380db757fe06bcc6108dd18e650a7c37c03a Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 6 Dec 2023 21:26:56 -0600 Subject: [PATCH 008/168] Clean up and add particle effects for machines (#2249) --- .../SimpleMachineMetaTileEntity.java | 28 ++- .../metatileentity/SteamMetaTileEntity.java | 33 ++- .../multiblock/MultiblockWithDisplayBase.java | 5 +- .../particle/IMachineParticleEffect.java | 10 + .../particle/VanillaParticleEffects.java | 204 ++++++++++++++++++ .../metatileentities/MetaTileEntities.java | 6 +- .../MetaTileEntitySingleCombustion.java | 11 + .../SimpleMachineMetaTileEntityResizable.java | 23 +- .../multi/MetaTileEntityCokeOven.java | 28 +-- .../MetaTileEntityPrimitiveBlastFurnace.java | 42 +--- .../MetaTileEntityMufflerHatch.java | 33 +-- .../steam/MetaTileEntitySteamGrinder.java | 10 + .../multi/steam/MetaTileEntitySteamOven.java | 15 ++ .../steam/SteamAlloySmelter.java | 9 +- .../steam/SteamExtractor.java | 7 +- .../metatileentities/steam/SteamFurnace.java | 20 +- .../metatileentities/steam/SteamHammer.java | 5 +- .../steam/SteamMacerator.java | 21 +- .../steam/SteamRockBreaker.java | 7 +- .../steam/boiler/SteamBoiler.java | 35 ++- .../steam/boiler/SteamLavaBoiler.java | 19 +- 21 files changed, 416 insertions(+), 155 deletions(-) create mode 100644 src/main/java/gregtech/client/particle/IMachineParticleEffect.java create mode 100644 src/main/java/gregtech/client/particle/VanillaParticleEffects.java diff --git a/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java index b5746f071c0..d479ec233f0 100644 --- a/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java @@ -15,6 +15,7 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; +import gregtech.client.particle.IMachineParticleEffect; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; @@ -77,6 +78,11 @@ public class SimpleMachineMetaTileEntity extends WorkableTieredMetaTileEntity private static final int FONT_HEIGHT = 9; // Minecraft's FontRenderer FONT_HEIGHT value + @Nullable // particle run every tick when the machine is active + protected final IMachineParticleEffect tickingParticle; + @Nullable // particle run in randomDisplayTick() when the machine is active + protected final IMachineParticleEffect randomParticle; + public SimpleMachineMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap recipeMap, ICubeRenderer renderer, int tier, boolean hasFrontFacing) { this(metaTileEntityId, recipeMap, renderer, tier, hasFrontFacing, GTUtility.defaultTankSizeFunction); @@ -85,15 +91,25 @@ public SimpleMachineMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap< public SimpleMachineMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap recipeMap, ICubeRenderer renderer, int tier, boolean hasFrontFacing, Function tankScalingFunction) { + this(metaTileEntityId, recipeMap, renderer, tier, hasFrontFacing, tankScalingFunction, null, null); + } + + public SimpleMachineMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap recipeMap, + ICubeRenderer renderer, int tier, boolean hasFrontFacing, + Function tankScalingFunction, + @Nullable IMachineParticleEffect tickingParticle, + @Nullable IMachineParticleEffect randomParticle) { super(metaTileEntityId, recipeMap, renderer, tier, tankScalingFunction); this.hasFrontFacing = hasFrontFacing; this.chargerInventory = new GTItemStackHandler(this, 1); + this.tickingParticle = tickingParticle; + this.randomParticle = randomParticle; } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new SimpleMachineMetaTileEntity(metaTileEntityId, workable.getRecipeMap(), renderer, getTier(), - hasFrontFacing, getTankScalingFunction()); + hasFrontFacing, getTankScalingFunction(), tickingParticle, randomParticle); } @Override @@ -189,6 +205,16 @@ public void update() { pushItemsIntoNearbyHandlers(getOutputFacingItems()); } } + } else if (this.tickingParticle != null && isActive()) { + tickingParticle.runEffect(this); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void randomDisplayTick() { + if (this.randomParticle != null && isActive()) { + randomParticle.runEffect(this); } } diff --git a/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java index a2c53bda0f1..c6e879fffc0 100644 --- a/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java @@ -10,6 +10,7 @@ import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTUtility; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -35,6 +36,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -143,32 +145,21 @@ public SoundEvent getSound() { @Override public void randomDisplayTick() { if (this.isActive()) { - final BlockPos pos = getPos(); - float x = pos.getX() + 0.5F; - float z = pos.getZ() + 0.5F; - - final EnumFacing facing = getFrontFacing(); - final float horizontalOffset = GTValues.RNG.nextFloat() * 0.6F - 0.3F; - final float y = pos.getY() + GTValues.RNG.nextFloat() * 0.375F; - - if (facing.getAxis() == EnumFacing.Axis.X) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) x += 0.52F; - else x -= 0.52F; - z += horizontalOffset; - } else if (facing.getAxis() == EnumFacing.Axis.Z) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) z += 0.52F; - else z -= 0.52F; - x += horizontalOffset; - } + EnumParticleTypes smokeParticle = isHighPressure ? EnumParticleTypes.SMOKE_LARGE : + EnumParticleTypes.SMOKE_NORMAL; + VanillaParticleEffects.defaultFrontEffect(this, smokeParticle, EnumParticleTypes.FLAME); + if (ConfigHolder.machines.machineSounds && GTValues.RNG.nextDouble() < 0.1) { - getWorld().playSound(x, y, z, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, - false); + BlockPos pos = getPos(); + getWorld().playSound(pos.getX(), pos.getY(), pos.getZ(), + SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); } - randomDisplayTick(x, y, z, EnumParticleTypes.FLAME, - isHighPressure ? EnumParticleTypes.SMOKE_LARGE : EnumParticleTypes.SMOKE_NORMAL); } } + /** @deprecated No longer used, look at {@link VanillaParticleEffects#defaultFrontEffect} to see old logic. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @SideOnly(Side.CLIENT) protected void randomDisplayTick(float x, float y, float z, EnumParticleTypes flame, EnumParticleTypes smoke) { getWorld().spawnParticle(smoke, x, y, z, 0, 0, 0); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java index c065b166997..a94c78ccdff 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java @@ -33,6 +33,7 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -274,8 +275,10 @@ public boolean isMufflerFaceFree() { } /** - * Produces the muffler particles + * @deprecated Use {@link gregtech.client.particle.VanillaParticleEffects#MUFFLER_SMOKE} instead. */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + @Deprecated @SideOnly(Side.CLIENT) public void runMufflerEffect(float xPos, float yPos, float zPos, float xSpd, float ySpd, float zSpd) { getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, xSpd, ySpd, zSpd); diff --git a/src/main/java/gregtech/client/particle/IMachineParticleEffect.java b/src/main/java/gregtech/client/particle/IMachineParticleEffect.java new file mode 100644 index 00000000000..aad4a0af202 --- /dev/null +++ b/src/main/java/gregtech/client/particle/IMachineParticleEffect.java @@ -0,0 +1,10 @@ +package gregtech.client.particle; + +import gregtech.api.metatileentity.MetaTileEntity; + +import org.jetbrains.annotations.NotNull; + +public interface IMachineParticleEffect { + + void runEffect(@NotNull MetaTileEntity metaTileEntity); +} diff --git a/src/main/java/gregtech/client/particle/VanillaParticleEffects.java b/src/main/java/gregtech/client/particle/VanillaParticleEffects.java new file mode 100644 index 00000000000..2765d3945d9 --- /dev/null +++ b/src/main/java/gregtech/client/particle/VanillaParticleEffects.java @@ -0,0 +1,204 @@ +package gregtech.client.particle; + +import gregtech.api.GTValues; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public enum VanillaParticleEffects implements IMachineParticleEffect { + + TOP_SMOKE_SMALL(mte -> { + if (mte.getWorld() == null || mte.getPos() == null) return; + if (mte.getFrontFacing() == EnumFacing.UP || mte.hasCover(EnumFacing.UP)) return; + + BlockPos pos = mte.getPos(); + float x = pos.getX() + 0.8F - GTValues.RNG.nextFloat() * 0.6F; + float y = pos.getY() + 0.9F + GTValues.RNG.nextFloat() * 0.2F; + float z = pos.getZ() + 0.8F - GTValues.RNG.nextFloat() * 0.6F; + mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y, z, 0, 0, 0); + }), + + MUFFLER_SMOKE(mte -> { + if (mte.getWorld() == null || mte.getPos() == null) return; + + BlockPos pos = mte.getPos(); + EnumFacing facing = mte.getFrontFacing(); + float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.25F; + float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; + float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.25F; + + float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); + float xSpd; + float zSpd; + + if (facing.getYOffset() == -1) { + float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; + xSpd = (float) Math.sin(temp) * 0.1F; + zSpd = (float) Math.cos(temp) * 0.1F; + } else { + xSpd = facing.getXOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); + zSpd = facing.getZOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); + } + + xPos += GTValues.RNG.nextFloat() * 0.5F; + yPos += GTValues.RNG.nextFloat() * 0.5F; + zPos += GTValues.RNG.nextFloat() * 0.5F; + + mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, xSpd, ySpd, zSpd); + }), + + PBF_SMOKE(mte -> { + if (mte.getWorld() == null || mte.getPos() == null) return; + + BlockPos pos = mte.getPos(); + EnumFacing facing = mte.getFrontFacing().getOpposite(); + float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.5F; + float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; + float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.5F; + + float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); + mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, 0, ySpd, 0); + }), + + RANDOM_LAVA_SMOKE(mte -> { + if (mte.getWorld() == null || mte.getPos() == null) return; + + EnumFacing facing = mte.getFrontFacing(); + if (facing.getAxis() == EnumFacing.Axis.Y || mte.hasCover(facing)) return; + BlockPos pos = mte.getPos(); + + final double offX = pos.getX() + facing.getXOffset() + 0.5D; + final double offY = pos.getY() + facing.getYOffset(); + final double offZ = pos.getZ() + facing.getZOffset() + 0.5D; + final double offset = -0.48D; + final double horizontal = GTValues.RNG.nextFloat() * 0.625D - 0.3125D; + + double x, z; + double y = offY + GTValues.RNG.nextFloat() * 0.375D; + + if (facing == EnumFacing.WEST) { + x = offX - offset; + z = offZ + horizontal; + } else if (facing == EnumFacing.EAST) { + x = offX + offset; + z = offZ + horizontal; + } else if (facing == EnumFacing.NORTH) { + x = offX + horizontal; + z = offZ - offset; + } else { // south + x = offX + horizontal; + z = offZ + offset; + } + + mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y, z, 0, 0, 0); + mte.getWorld().spawnParticle(EnumParticleTypes.LAVA, x, y, z, 0, 0, 0); + }), + + RANDOM_SPARKS(mte -> { + if (mte.getWorld() == null || mte.getPos() == null) return; + + EnumFacing facing = mte.getFrontFacing(); + if (facing.getAxis() == EnumFacing.Axis.Y || mte.hasCover(facing)) return; + + if (GTValues.RNG.nextInt(3) == 0) { + BlockPos pos = mte.getPos(); + + final double offset = 0.02D; + final double horizontal = 0.5D + GTValues.RNG.nextFloat() * 0.5D - 0.25D; + + double x, z, mX, mZ; + double y = pos.getY() + GTValues.RNG.nextFloat() * 0.625D + 0.3125D; + if (facing == EnumFacing.WEST) { + x = pos.getX() - offset; + mX = -0.05D; + z = pos.getZ() + horizontal; + mZ = 0.0D; + } else if (facing == EnumFacing.EAST) { + x = pos.getX() + offset; + mX = 0.05D; + z = pos.getZ() + horizontal; + mZ = 0.0D; + } else if (facing == EnumFacing.NORTH) { + x = pos.getX() + horizontal; + mX = 0.0D; + z = pos.getZ() - offset; + mZ = -0.05D; + } else { // south + x = pos.getX() + horizontal; + mX = 0.0D; + z = pos.getZ() + offset; + mZ = 0.05D; + } + + mte.getWorld().spawnParticle(EnumParticleTypes.LAVA, x, y, z, mX, 0, mZ); + } + }), + + COMBUSTION_SMOKE(mte -> { + if (mte.getWorld() == null || mte.getPos() == null) return; + if (mte.hasCover(EnumFacing.UP)) return; + BlockPos pos = mte.getPos(); + + float x = pos.getX() + 0.125F + GTValues.RNG.nextFloat() * 0.875F; + float y = pos.getY() + 1.03125F; + float z = pos.getZ() + 0.125F + GTValues.RNG.nextFloat() * 0.875F; + + mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y, z, 0, 0, 0); + }); + + // Wrap for client-sided stuff + private final Consumer effectConsumer; + + VanillaParticleEffects(Consumer effectConsumer) { + this.effectConsumer = effectConsumer; + } + + @Override + public void runEffect(@NotNull MetaTileEntity metaTileEntity) { + effectConsumer.accept(metaTileEntity); + } + + @SideOnly(Side.CLIENT) + public static void defaultFrontEffect(MetaTileEntity mte, EnumParticleTypes... particles) { + defaultFrontEffect(mte, 0.0F, particles); + } + + @SideOnly(Side.CLIENT) + public static void defaultFrontEffect(MetaTileEntity mte, float yOffset, EnumParticleTypes... particles) { + if (particles == null || particles.length == 0) return; + if (mte.getWorld() == null || mte.getPos() == null) return; + + BlockPos pos = mte.getPos(); + EnumFacing facing = mte.getFrontFacing(); + + if (facing.getAxis() == EnumFacing.Axis.Y || mte.hasCover(facing)) return; + + float x = pos.getX() + 0.5F; + float z = pos.getZ() + 0.5F; + + float horizontalOffset = GTValues.RNG.nextFloat() * 0.6F - 0.3F + yOffset; + float y = pos.getY() + GTValues.RNG.nextFloat() * 0.375F; + + if (facing.getAxis() == EnumFacing.Axis.X) { + if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) x += 0.52F; + else x -= 0.52F; + z += horizontalOffset; + } else if (facing.getAxis() == EnumFacing.Axis.Z) { + if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) z += 0.52F; + else z -= 0.52F; + x += horizontalOffset; + } + + for (EnumParticleTypes particle : particles) { + mte.getWorld().spawnParticle(particle, x, y, z, 0, 0, 0); + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 912811fa70a..a6ff769f8ec 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -13,6 +13,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; @@ -406,7 +407,10 @@ public static void init() { default -> 4; }, tier <= GTValues.MV ? Textures.MACERATOR_OVERLAY : Textures.PULVERIZER_OVERLAY, - tier)); + tier, + true, + GTUtility.defaultTankSizeFunction, + VanillaParticleEffects.TOP_SMOKE_SMALL, null)); // Alloy Smelter, IDs 80-94 registerSimpleMetaTileEntity(ALLOY_SMELTER, 80, "alloy_smelter", RecipeMaps.ALLOY_SMELTER_RECIPES, diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntitySingleCombustion.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntitySingleCombustion.java index 2c2c8fd360d..b18412bbabd 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntitySingleCombustion.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntitySingleCombustion.java @@ -4,10 +4,13 @@ import gregtech.api.metatileentity.SimpleGeneratorMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMap; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; @@ -46,4 +49,12 @@ protected void renderOverlays(CCRenderState renderState, Matrix4 translation, IV super.renderOverlays(renderState, translation, pipeline); } } + + @SideOnly(Side.CLIENT) + @Override + public void randomDisplayTick() { + if (isActive()) { + VanillaParticleEffects.COMBUSTION_SMOKE.runEffect(this); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/electric/SimpleMachineMetaTileEntityResizable.java b/src/main/java/gregtech/common/metatileentities/electric/SimpleMachineMetaTileEntityResizable.java index be43ffb1ab0..fa9d64c2897 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/SimpleMachineMetaTileEntityResizable.java +++ b/src/main/java/gregtech/common/metatileentities/electric/SimpleMachineMetaTileEntityResizable.java @@ -5,11 +5,14 @@ import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMap; +import gregtech.client.particle.IMachineParticleEffect; import gregtech.client.renderer.ICubeRenderer; import net.minecraft.util.ResourceLocation; import net.minecraftforge.items.IItemHandlerModifiable; +import org.jetbrains.annotations.Nullable; + import java.util.function.Function; /** @@ -58,6 +61,23 @@ public SimpleMachineMetaTileEntityResizable(ResourceLocation metaTileEntityId, initializeInventory(); } + public SimpleMachineMetaTileEntityResizable(ResourceLocation metaTileEntityId, + RecipeMap recipeMap, + int inputAmount, + int outputAmount, + ICubeRenderer renderer, + int tier, + boolean hasFrontFacing, + Function tankScalingFunction, + @Nullable IMachineParticleEffect tickingParticle, + @Nullable IMachineParticleEffect randomParticle) { + super(metaTileEntityId, recipeMap, renderer, tier, hasFrontFacing, tankScalingFunction, tickingParticle, + randomParticle); + this.inputAmount = inputAmount; + this.outputAmount = outputAmount; + initializeInventory(); + } + @Override protected IItemHandlerModifiable createImportItemHandler() { if (inputAmount != -1) { @@ -77,7 +97,8 @@ protected IItemHandlerModifiable createExportItemHandler() { @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new SimpleMachineMetaTileEntityResizable(metaTileEntityId, workable.getRecipeMap(), inputAmount, - outputAmount, renderer, getTier()); + outputAmount, renderer, getTier(), hasFrontFacing(), + getTankScalingFunction(), tickingParticle, randomParticle); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOven.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOven.java index 8d54fc54adb..781ae14b7e3 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOven.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOven.java @@ -12,6 +12,7 @@ import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; @@ -47,6 +48,7 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityCokeOven(metaTileEntityId); } + @NotNull @Override protected BlockPattern createStructurePattern() { return FactoryBlockPattern.start() @@ -112,29 +114,13 @@ protected ModularUI.Builder createUITemplate(EntityPlayer entityPlayer) { @Override public void randomDisplayTick() { if (this.isActive()) { - final BlockPos pos = getPos(); - float x = pos.getX() + 0.5F; - float z = pos.getZ() + 0.5F; - - final EnumFacing facing = getFrontFacing(); - final float horizontalOffset = GTValues.RNG.nextFloat() * 0.6F - 0.3F; - final float y = pos.getY() + GTValues.RNG.nextFloat() * 0.375F + 0.3F; - - if (facing.getAxis() == EnumFacing.Axis.X) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) x += 0.52F; - else x -= 0.52F; - z += horizontalOffset; - } else if (facing.getAxis() == EnumFacing.Axis.Z) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) z += 0.52F; - else z -= 0.52F; - x += horizontalOffset; - } + VanillaParticleEffects.defaultFrontEffect(this, 0.3F, EnumParticleTypes.SMOKE_LARGE, + EnumParticleTypes.FLAME); if (ConfigHolder.machines.machineSounds && GTValues.RNG.nextDouble() < 0.1) { - getWorld().playSound(x, y, z, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, - false); + BlockPos pos = getPos(); + getWorld().playSound(pos.getX(), pos.getY(), pos.getZ(), + SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); } - getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, x, y, z, 0, 0, 0); - getWorld().spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0); } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveBlastFurnace.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveBlastFurnace.java index 0dad1c14ee1..90078eaf604 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveBlastFurnace.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveBlastFurnace.java @@ -16,6 +16,7 @@ import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.recipes.RecipeMaps; import gregtech.api.util.GTUtility; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.cclop.ColourOperation; @@ -58,6 +59,7 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityPrimitiveBlastFurnace(metaTileEntityId); } + @NotNull @Override protected BlockPattern createStructurePattern() { return FactoryBlockPattern.start() @@ -137,24 +139,13 @@ public void update() { if (this.isActive()) { if (getWorld().isRemote) { - pollutionParticles(); + VanillaParticleEffects.PBF_SMOKE.runEffect(this); } else { damageEntitiesAndBreakSnow(); } } } - private void pollutionParticles() { - BlockPos pos = this.getPos(); - EnumFacing facing = this.getFrontFacing().getOpposite(); - float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.5F; - float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; - float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.5F; - - float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); - runMufflerEffect(xPos, yPos, zPos, 0, ySpd, 0); - } - private void damageEntitiesAndBreakSnow() { BlockPos middlePos = this.getPos(); middlePos = middlePos.offset(getFrontFacing().getOpposite()); @@ -167,32 +158,17 @@ private void damageEntitiesAndBreakSnow() { } } + @SideOnly(Side.CLIENT) @Override public void randomDisplayTick() { if (this.isActive()) { - final BlockPos pos = getPos(); - float x = pos.getX() + 0.5F; - float z = pos.getZ() + 0.5F; - - final EnumFacing facing = getFrontFacing(); - final float horizontalOffset = GTValues.RNG.nextFloat() * 0.6F - 0.3F; - final float y = pos.getY() + GTValues.RNG.nextFloat() * 0.375F + 0.3F; - - if (facing.getAxis() == EnumFacing.Axis.X) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) x += 0.52F; - else x -= 0.52F; - z += horizontalOffset; - } else if (facing.getAxis() == EnumFacing.Axis.Z) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) z += 0.52F; - else z -= 0.52F; - x += horizontalOffset; - } + VanillaParticleEffects.defaultFrontEffect(this, 0.3F, EnumParticleTypes.SMOKE_LARGE, + EnumParticleTypes.FLAME); if (ConfigHolder.machines.machineSounds && GTValues.RNG.nextDouble() < 0.1) { - getWorld().playSound(x, y, z, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, - false); + BlockPos pos = getPos(); + getWorld().playSound(pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F, + SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); } - getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, x, y, z, 0, 0, 0); - getWorld().spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index fd934d13813..4b3e75a4c2c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -14,6 +14,7 @@ import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -22,7 +23,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -33,6 +33,7 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -68,7 +69,7 @@ public void update() { if (getWorld().isRemote && getController() instanceof MultiblockWithDisplayBase controller && controller.isActive()) { - pollutionParticles(); + VanillaParticleEffects.MUFFLER_SMOKE.runEffect(this); } } @@ -111,32 +112,12 @@ private boolean checkFrontFaceFree() { return blockState.getBlock().isAir(blockState, getWorld(), frontPos) || GTUtility.isBlockSnow(blockState); } + /** @deprecated Use {@link VanillaParticleEffects#MUFFLER_SMOKE} instead. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @SideOnly(Side.CLIENT) public void pollutionParticles() { - BlockPos pos = this.getPos(); - EnumFacing facing = this.getFrontFacing(); - float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.25F; - float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; - float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.25F; - - float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); - float xSpd; - float zSpd; - - if (facing.getYOffset() == -1) { - float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; - xSpd = (float) Math.sin(temp) * 0.1F; - zSpd = (float) Math.cos(temp) * 0.1F; - } else { - xSpd = facing.getXOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); - zSpd = facing.getZOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); - } - if (getController() instanceof MultiblockWithDisplayBase) - ((MultiblockWithDisplayBase) getController()).runMufflerEffect( - xPos + GTValues.RNG.nextFloat() * 0.5F, - yPos + GTValues.RNG.nextFloat() * 0.5F, - zPos + GTValues.RNG.nextFloat() * 0.5F, - xSpd, ySpd, zSpd); + VanillaParticleEffects.MUFFLER_SMOKE.runEffect(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamGrinder.java b/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamGrinder.java index 2707e903afa..804980f7952 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamGrinder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamGrinder.java @@ -8,6 +8,7 @@ import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -18,6 +19,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; @@ -95,4 +97,12 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.universal.tooltip.parallel", PARALLEL_LIMIT)); tooltip.add(TooltipHelper.BLINKING_ORANGE + I18n.format("gregtech.multiblock.require_steam_parts")); } + + @SideOnly(Side.CLIENT) + @Override + public void randomDisplayTick() { + if (isActive()) { + VanillaParticleEffects.defaultFrontEffect(this, 0.4F, EnumParticleTypes.SMOKE_NORMAL); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamOven.java b/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamOven.java index c800f3d1a54..b3a3e5fa039 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamOven.java +++ b/src/main/java/gregtech/common/metatileentities/multi/steam/MetaTileEntitySteamOven.java @@ -1,5 +1,6 @@ package gregtech.common.metatileentities.multi.steam; +import gregtech.api.GTValues; import gregtech.api.capability.impl.SteamMultiWorkable; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -8,6 +9,7 @@ import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -19,6 +21,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; @@ -44,6 +47,7 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntitySteamOven(metaTileEntityId); } + @NotNull @Override protected BlockPattern createStructurePattern() { return FactoryBlockPattern.start() @@ -118,4 +122,15 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.universal.tooltip.parallel", MAX_PARALLELS)); tooltip.add(TooltipHelper.BLINKING_ORANGE + I18n.format("gregtech.multiblock.require_steam_parts")); } + + @SideOnly(Side.CLIENT) + @Override + public void randomDisplayTick() { + if (isActive()) { + VanillaParticleEffects.defaultFrontEffect(this, EnumParticleTypes.SMOKE_LARGE, EnumParticleTypes.FLAME); + if (GTValues.RNG.nextBoolean()) { + VanillaParticleEffects.defaultFrontEffect(this, 0.5F, EnumParticleTypes.SMOKE_NORMAL); + } + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamAlloySmelter.java b/src/main/java/gregtech/common/metatileentities/steam/SteamAlloySmelter.java index c75459c8df7..b0ed0494fed 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamAlloySmelter.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamAlloySmelter.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -60,10 +61,10 @@ public ModularUI createUI(EntityPlayer player) { @SideOnly(Side.CLIENT) @Override - protected void randomDisplayTick(float x, float y, float z, EnumParticleTypes flame, EnumParticleTypes smoke) { - super.randomDisplayTick(x, y, z, flame, smoke); - if (GTValues.RNG.nextBoolean()) { - getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y + 0.5F, z, 0, 0, 0); + public void randomDisplayTick() { + super.randomDisplayTick(); + if (isActive() && GTValues.RNG.nextBoolean()) { + VanillaParticleEffects.defaultFrontEffect(this, 0.5F, EnumParticleTypes.SMOKE_NORMAL); } } } diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamExtractor.java b/src/main/java/gregtech/common/metatileentities/steam/SteamExtractor.java index e71cc0d1201..efd65e3c499 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamExtractor.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamExtractor.java @@ -8,6 +8,7 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -52,7 +53,9 @@ public ModularUI createUI(EntityPlayer player) { @SideOnly(Side.CLIENT) @Override - protected void randomDisplayTick(float x, float y, float z, EnumParticleTypes flame, EnumParticleTypes smoke) { - getWorld().spawnParticle(EnumParticleTypes.CLOUD, x, y, z, 0, 0, 0); + public void randomDisplayTick() { + if (isActive()) { + VanillaParticleEffects.defaultFrontEffect(this, EnumParticleTypes.CLOUD); + } } } diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamFurnace.java b/src/main/java/gregtech/common/metatileentities/steam/SteamFurnace.java index ec1bfb1b2e9..30e3fb89850 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamFurnace.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamFurnace.java @@ -1,5 +1,6 @@ package gregtech.common.metatileentities.steam; +import gregtech.api.GTValues; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; @@ -8,11 +9,16 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; +import gregtech.common.ConfigHolder; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandlerModifiable; @@ -57,7 +63,17 @@ public ModularUI createUI(EntityPlayer player) { @SideOnly(Side.CLIENT) @Override - protected void randomDisplayTick(float x, float y, float z, EnumParticleTypes flame, EnumParticleTypes smoke) { - super.randomDisplayTick(x, y + 0.5F, z, flame, smoke); + public void randomDisplayTick() { + if (this.isActive()) { + EnumParticleTypes smokeParticle = isHighPressure ? EnumParticleTypes.SMOKE_LARGE : + EnumParticleTypes.SMOKE_NORMAL; + VanillaParticleEffects.defaultFrontEffect(this, 0.5F, smokeParticle, EnumParticleTypes.FLAME); + + if (ConfigHolder.machines.machineSounds && GTValues.RNG.nextDouble() < 0.1) { + BlockPos pos = getPos(); + getWorld().playSound(pos.getX(), pos.getY(), pos.getZ(), + SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); + } + } } } diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamHammer.java b/src/main/java/gregtech/common/metatileentities/steam/SteamHammer.java index f31bc66214f..576b8e6f180 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamHammer.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamHammer.java @@ -8,6 +8,7 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -53,6 +54,8 @@ public ModularUI createUI(EntityPlayer player) { @SideOnly(Side.CLIENT) @Override public void randomDisplayTick() { - // steam hammers do not make particles + if (isActive()) { + VanillaParticleEffects.RANDOM_SPARKS.runEffect(this); + } } } diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamMacerator.java b/src/main/java/gregtech/common/metatileentities/steam/SteamMacerator.java index 51a3716025d..869839f8c39 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamMacerator.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamMacerator.java @@ -1,6 +1,5 @@ package gregtech.common.metatileentities.steam; -import gregtech.api.GTValues; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; @@ -9,12 +8,11 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandlerModifiable; @@ -58,16 +56,17 @@ public int getItemOutputLimit() { return 1; } + @Override + public void update() { + super.update(); + if (isActive() && getWorld().isRemote) { + VanillaParticleEffects.TOP_SMOKE_SMALL.runEffect(this); + } + } + @SideOnly(Side.CLIENT) @Override public void randomDisplayTick() { - if (isActive()) { - final BlockPos pos = getPos(); - final float horizontalOffset = GTValues.RNG.nextFloat() * 0.6F - 0.3F; - getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, pos.getX() + horizontalOffset, pos.getY() + 0.52F, - pos.getZ() + horizontalOffset, - GTValues.RNG.nextFloat() * 0.125F, GTValues.RNG.nextFloat() * 0.375F, - GTValues.RNG.nextFloat() * 0.125F); - } + // steam macerators do not make particles in this way } } diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamRockBreaker.java b/src/main/java/gregtech/common/metatileentities/steam/SteamRockBreaker.java index 5dbf91b5d8e..21ba4e49276 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamRockBreaker.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamRockBreaker.java @@ -10,6 +10,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import net.minecraft.block.Block; @@ -116,8 +117,10 @@ public void readFromNBT(NBTTagCompound data) { @SideOnly(Side.CLIENT) @Override - protected void randomDisplayTick(float x, float y, float z, EnumParticleTypes flame, EnumParticleTypes smoke) { - getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y + 0.4F, z, 0, 0, 0); + public void randomDisplayTick() { + if (isActive()) { + VanillaParticleEffects.defaultFrontEffect(this, 0.4F, EnumParticleTypes.SMOKE_NORMAL); + } } protected class SteamRockBreakerRecipeLogic extends RecipeLogicSteam { diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java index cd9356f0825..a39ebdfff58 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java @@ -18,6 +18,7 @@ import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.TextFormattingUtil; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -48,6 +49,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -386,32 +388,21 @@ public List getDataInfo() { @Override public void randomDisplayTick() { if (this.isActive()) { - final BlockPos pos = getPos(); - float x = pos.getX() + 0.5F; - float z = pos.getZ() + 0.5F; - - if (GTValues.RNG.nextDouble() < 0.1) { - getWorld().playSound(x, pos.getY(), z + 0.5F, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, - SoundCategory.BLOCKS, 1.0F, 1.0F, false); - } - - final EnumFacing facing = getFrontFacing(); - final float horizontalOffset = GTValues.RNG.nextFloat() * 0.6F - 0.3F; - final float y = pos.getY() + GTValues.RNG.nextFloat() * 0.375F; - - if (facing.getAxis() == EnumFacing.Axis.X) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) x += 0.52F; - else x -= 0.52F; - z += horizontalOffset; - } else if (facing.getAxis() == EnumFacing.Axis.Z) { - if (facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE) z += 0.52F; - else z -= 0.52F; - x += horizontalOffset; + EnumParticleTypes smokeParticle = isHighPressure ? EnumParticleTypes.SMOKE_LARGE : + EnumParticleTypes.SMOKE_NORMAL; + VanillaParticleEffects.defaultFrontEffect(this, smokeParticle, EnumParticleTypes.FLAME); + + if (ConfigHolder.machines.machineSounds && GTValues.RNG.nextDouble() < 0.1) { + BlockPos pos = getPos(); + getWorld().playSound(pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F, + SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); } - randomDisplayTick(x, y, z); } } + /** @deprecated No longer used, look at {@link VanillaParticleEffects#defaultFrontEffect} to see old logic. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @SideOnly(Side.CLIENT) protected void randomDisplayTick(float x, float y, float z) { getWorld().spawnParticle(isHighPressure ? EnumParticleTypes.SMOKE_LARGE : EnumParticleTypes.SMOKE_NORMAL, x, y, diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java index 421cc9843df..1269bf30450 100755 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java @@ -11,11 +11,15 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.unification.material.Materials; +import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; +import gregtech.common.ConfigHolder; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumParticleTypes; +import net.minecraft.init.SoundEvents; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; @@ -126,11 +130,14 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { @SideOnly(Side.CLIENT) @Override - public void randomDisplayTick(float x, float y, float z) { - super.randomDisplayTick(x, y, z); - if (GTValues.RNG.nextFloat() < 0.3F) { - getWorld().spawnParticle(EnumParticleTypes.LAVA, x + GTValues.RNG.nextFloat(), y, - z + GTValues.RNG.nextFloat(), 0.0F, 0.0F, 0.0F); + public void randomDisplayTick() { + if (this.isActive()) { + VanillaParticleEffects.RANDOM_LAVA_SMOKE.runEffect(this); + if (ConfigHolder.machines.machineSounds && GTValues.RNG.nextDouble() < 0.1) { + BlockPos pos = getPos(); + getWorld().playSound(pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F, + SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false); + } } } } From 4a4205ce83eec4cba8273da54d6f9657cd8de601 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:49:12 -0600 Subject: [PATCH 009/168] Fix fluid output trim losing some fluids (#2268) --- src/main/java/gregtech/api/recipes/Recipe.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java index e09519f4dde..b291f994301 100644 --- a/src/main/java/gregtech/api/recipes/Recipe.java +++ b/src/main/java/gregtech/api/recipes/Recipe.java @@ -562,23 +562,24 @@ public Pair, List> getFluidAndChanceOutputs outputs.addAll(GTUtility.copyFluidList(getFluidOutputs())); } // If just the regular outputs would satisfy the outputLimit - else if (getOutputs().size() >= outputLimit) { + else if (getFluidOutputs().size() >= outputLimit) { outputs.addAll( - GTUtility.copyFluidList(getFluidOutputs()).subList(0, Math.min(outputLimit, getOutputs().size()))); + GTUtility.copyFluidList(getFluidOutputs()).subList(0, + Math.min(outputLimit, getFluidOutputs().size()))); // clear the chanced outputs, as we are only getting regular outputs chancedOutputs.clear(); } // If the regular outputs and chanced outputs are required to satisfy the outputLimit - else if (!getOutputs().isEmpty() && (getOutputs().size() + chancedOutputs.size()) >= outputLimit) { + else if (!getFluidOutputs().isEmpty() && (getFluidOutputs().size() + chancedOutputs.size()) >= outputLimit) { outputs.addAll(GTUtility.copyFluidList(getFluidOutputs())); // Calculate the number of chanced outputs after adding all the regular outputs - int numChanced = outputLimit - getOutputs().size(); + int numChanced = outputLimit - getFluidOutputs().size(); chancedOutputs = chancedOutputs.subList(0, Math.min(numChanced, chancedOutputs.size())); } // There are only chanced outputs to satisfy the outputLimit - else if (getOutputs().isEmpty()) { + else if (getFluidOutputs().isEmpty()) { chancedOutputs = chancedOutputs.subList(0, Math.min(outputLimit, chancedOutputs.size())); } // The number of outputs + chanced outputs is lower than the trim number, so just add everything From a6f50578492165f66f6f25464f4934e74adbfbd7 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 9 Dec 2023 20:34:49 -0500 Subject: [PATCH 010/168] fix crash with fluid filters with null delegate containers (#2273) --- .../capability/impl/FluidHandlerDelegate.java | 3 ++- .../gregtech/common/covers/CoverFluidFilter.java | 14 ++++++++------ .../java/gregtech/common/covers/CoverPump.java | 16 +++++++++++++--- .../MetaTileEntityLDFluidEndpoint.java | 3 ++- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/FluidHandlerDelegate.java b/src/main/java/gregtech/api/capability/impl/FluidHandlerDelegate.java index f6e2a369aba..0449a6b3dfb 100644 --- a/src/main/java/gregtech/api/capability/impl/FluidHandlerDelegate.java +++ b/src/main/java/gregtech/api/capability/impl/FluidHandlerDelegate.java @@ -4,13 +4,14 @@ import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class FluidHandlerDelegate implements IFluidHandler { public final IFluidHandler delegate; - public FluidHandlerDelegate(IFluidHandler delegate) { + public FluidHandlerDelegate(@NotNull IFluidHandler delegate) { this.delegate = delegate; } diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index c746215c983..cd5d06ee5a4 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -110,13 +110,15 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra } @Override - public T getCapability(@NotNull Capability capability, T defaultValue) { + public T getCapability(@NotNull Capability capability, @Nullable T defaultValue) { if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { - IFluidHandler delegate = (IFluidHandler) defaultValue; - if (fluidHandler == null || fluidHandler.delegate != delegate) { - this.fluidHandler = new FluidHandlerFiltered(delegate); + if (defaultValue instanceof IFluidHandler delegate) { + if (fluidHandler == null || fluidHandler.delegate != delegate) { + this.fluidHandler = new FluidHandlerFiltered(delegate); + } + return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(fluidHandler); } - return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(fluidHandler); + return null; } return defaultValue; } @@ -141,7 +143,7 @@ public void readFromNBT(@NotNull NBTTagCompound tagCompound) { private class FluidHandlerFiltered extends FluidHandlerDelegate { - public FluidHandlerFiltered(IFluidHandler delegate) { + public FluidHandlerFiltered(@NotNull IFluidHandler delegate) { super(delegate); } diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index ebd53eefe50..961e349be6b 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -11,7 +11,12 @@ import gregtech.api.cover.CoverableView; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.CycleButtonWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.IncrementButtonWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.TextFieldWidget2; +import gregtech.api.gui.widgets.WidgetGroup; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -23,7 +28,12 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.ITickable; import net.minecraft.util.math.MathHelper; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidStack; @@ -397,7 +407,7 @@ public String getName() { private class CoverableFluidHandlerWrapper extends FluidHandlerDelegate { - public CoverableFluidHandlerWrapper(IFluidHandler delegate) { + public CoverableFluidHandlerWrapper(@NotNull IFluidHandler delegate) { super(delegate); } diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/longdistance/MetaTileEntityLDFluidEndpoint.java b/src/main/java/gregtech/common/pipelike/fluidpipe/longdistance/MetaTileEntityLDFluidEndpoint.java index 3602e89f3f8..55ddb9d3ba1 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/longdistance/MetaTileEntityLDFluidEndpoint.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/longdistance/MetaTileEntityLDFluidEndpoint.java @@ -27,6 +27,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class MetaTileEntityLDFluidEndpoint extends MetaTileEntityLongDistanceEndpoint { @@ -101,7 +102,7 @@ public Pair getParticleTexture() { private static class FluidHandlerWrapper extends FluidHandlerDelegate { - public FluidHandlerWrapper(IFluidHandler delegate) { + public FluidHandlerWrapper(@NotNull IFluidHandler delegate) { super(delegate); } From 471ef1f105d4f8d0fab41f3ee4b7252fab1055e6 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 9 Dec 2023 23:43:45 -0500 Subject: [PATCH 011/168] fix data stick entry removal from AL (#2279) --- .../gregtech/api/recipes/machines/RecipeMapAssemblyLine.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java index efd953ea099..0b9cd8099be 100644 --- a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java +++ b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java @@ -103,8 +103,9 @@ public boolean removeRecipe(@NotNull Recipe recipe) { ResearchPropertyData data = recipe.getProperty(ResearchProperty.getInstance(), null); if (data != null) { for (ResearchPropertyData.ResearchEntry entry : data) { - return removeDataStickEntry(entry.getResearchId(), recipe); + removeDataStickEntry(entry.getResearchId(), recipe); } + return true; } return false; } From 195d75e037e5d79e02ffa1e83a528b400c534030 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 10 Dec 2023 19:32:57 -0700 Subject: [PATCH 012/168] Fix Large Gas Turbine not displaying Max Voltage when fully spun up (#2283) --- .../multi/electric/generator/MetaTileEntityLargeTurbine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java index 777307110af..16522799167 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java @@ -106,7 +106,7 @@ protected void formStructure(PatternMatchContext context) { protected long getMaxVoltage() { long maxProduction = recipeMapWorkable.getMaxVoltage(); long currentProduction = ((LargeTurbineWorkableHandler) recipeMapWorkable).boostProduction((int) maxProduction); - if (isActive() && currentProduction < maxProduction) { + if (isActive() && currentProduction <= maxProduction) { return recipeMapWorkable.getMaxVoltage(); } else { return 0L; From bbf9b9853fcdf6146f09131cc750e70c65ebee23 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 11 Dec 2023 17:59:41 -0600 Subject: [PATCH 013/168] Update build script version to 1702244235 (#2282) Co-authored-by: DStrand1 Co-authored-by: alongstringofnumbers --- build.gradle | 12 +++++++++--- gradle.properties | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 5e4447c6c45..29b2ba602bf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1701739812 +//version: 1702244235 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -79,6 +79,7 @@ propertyDefaultIfUnset("curseForgeRelations", "") propertyDefaultIfUnsetWithEnvVar("releaseType", "release", "RELEASE_TYPE") propertyDefaultIfUnset("generateDefaultChangelog", false) propertyDefaultIfUnset("customMavenPublishUrl", "") +propertyDefaultIfUnset("mavenArtifactGroup", getDefaultArtifactGroup()) propertyDefaultIfUnset("enableModernJavaSyntax", false) propertyDefaultIfUnset("enableSpotless", false) propertyDefaultIfUnset("enableJUnit", false) @@ -984,8 +985,8 @@ if (customMavenPublishUrl) { } // providers is not available here, use System for getting env vars - groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.group - artifactId = System.getenv('ARTIFACT_ID') ?: project.name + groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.mavenArtifactGroup + artifactId = System.getenv('ARTIFACT_ID') ?: project.modArchivesBaseName version = System.getenv('RELEASE_VERSION') ?: publishedVersion } } @@ -1130,6 +1131,11 @@ tasks.register('faq') { // Helpers +def getDefaultArtifactGroup() { + def lastIndex = project.modGroup.lastIndexOf('.') + return lastIndex < 0 ? project.modGroup : project.modGroup.substring(0, lastIndex) +} + def getFile(String relativePath) { return new File(projectDir, relativePath) } diff --git a/gradle.properties b/gradle.properties index e7b28291e09..85aff107251 100644 --- a/gradle.properties +++ b/gradle.properties @@ -52,6 +52,8 @@ accessTransformersFile = gregtech_at.cfg usesMixins = false # Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! mixinsPackage = +# Automatically generates a mixin config json if enabled, with the name mixins.modid.json +generateMixinConfig=false # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin coreModClass = asm.GregTechLoadingPlugin @@ -75,6 +77,7 @@ includeWellKnownRepositories = true # Overrides the above setting to be always true, as these repositories are needed to fetch the mods includeCommonDevEnvMods = true + # If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your # responsibility check the licence and request permission for distribution, if required. usesShadowedDependencies = false @@ -120,6 +123,7 @@ curseForgeProjectId = curseForgeRelations = requiredDependency:codechicken-lib-1-8;incompatible:gregtechce # This project's release type on CurseForge and/or Modrinth +# Alternatively this can be set with the 'RELEASE_TYPE' environment variable. # Allowed types: release, beta, alpha releaseType = beta @@ -129,6 +133,17 @@ generateDefaultChangelog = false # Prevent the source code from being published noPublishedSources = false +# Publish to a custom maven location. Follows a few rules: +# Group ID can be set with the 'ARTIFACT_GROUP_ID' environment variable, default to 'project.group' +# Artifact ID can be set with the 'ARTIFACT_ID' environment variable, default to 'project.name' +# Version can be set with the 'RELEASE_VERSION' environment variable, default to 'modVersion' +# For maven credentials: +# Username is set with the 'MAVEN_USER' environment variable, default to "NONE" +# Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE" +customMavenPublishUrl= +# The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any). +# So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname' +mavenArtifactGroup= # Enable spotless checks # Enforces code formatting on your source code From d09b51799bddc282c60c1e3a64736b9d76d6b44c Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 11 Dec 2023 23:45:32 -0600 Subject: [PATCH 014/168] 2.8.3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 85aff107251..8ef839c11f9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.2-beta +modVersion = 2.8.3-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From 34408eb505155511059267ea08a650036f46d5d3 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:30:53 -0600 Subject: [PATCH 015/168] Fix addFluid expansion method for GrS/CT (#2287) --- .../material/CTMaterialHelpers.java | 2 +- .../material/MaterialPropertyExpansion.java | 23 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java index 751be8aa3ef..ca5d08a1efa 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java @@ -22,7 +22,7 @@ protected static FluidState validateFluidState(String fluidTypeName) { if (fluidTypeName.equals("gas")) return FluidState.GAS; if (fluidTypeName.equals("plasma")) return FluidState.PLASMA; - String message = "Fluid Type must be either \"liquid\", \"gas\", or \"acid\"!"; + String message = "Fluid Type must be either \"liquid\", \"gas\", or \"plasma\"!"; CraftTweakerAPI.logError(message); throw new IllegalArgumentException(message); } diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java index 0f2c7a3d882..bf4624282cb 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java @@ -156,20 +156,27 @@ public static void addFluid(Material m) { public static void addFluid(Material m, @Optional String fluidTypeName, @Optional boolean hasBlock) { if (checkFrozen("add a Fluid to a material")) return; FluidState type = validateFluidState(fluidTypeName); - if (m.hasProperty(PropertyKey.FLUID)) { - FluidStorage storage = m.getProperty(PropertyKey.FLUID).getStorage(); - FluidBuilder builder = new FluidBuilder(); - if (hasBlock) builder.block(); + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (property == null) { + property = new FluidProperty(); + m.setProperty(PropertyKey.FLUID, property); + } + + FluidStorage storage = property.getStorage(); + FluidBuilder builder = switch (type) { + case LIQUID -> storage.getQueuedBuilder(FluidStorageKeys.LIQUID); + case GAS -> storage.getQueuedBuilder(FluidStorageKeys.GAS); + case PLASMA -> storage.getQueuedBuilder(FluidStorageKeys.PLASMA); + }; + if (builder == null) { + builder = new FluidBuilder(); switch (type) { case LIQUID -> storage.enqueueRegistration(FluidStorageKeys.LIQUID, builder); case GAS -> storage.enqueueRegistration(FluidStorageKeys.GAS, builder.state(FluidState.GAS)); case PLASMA -> storage.enqueueRegistration(FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); } - } else { - FluidProperty property = new FluidProperty(); - property.getStorage().enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); - m.setProperty(PropertyKey.FLUID, property); } + if (hasBlock) builder.block(); } @ZenMethod From 62baffcf18226b93655e88eb4f800507d1f541e0 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:38:32 -0600 Subject: [PATCH 016/168] More tool compat (#2292) --- .../railcraft/api/items/IToolCrowbar.java | 78 +++++++++++++++++++ .../mrtjp/projectred/api/IScrewdriver.java | 11 +++ src/main/java/gregtech/api/GTValues.java | 4 +- .../gregtech/api/items/toolitem/IGTTool.java | 50 +++++++++++- 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/api/java/mods/railcraft/api/items/IToolCrowbar.java create mode 100644 src/api/java/mrtjp/projectred/api/IScrewdriver.java diff --git a/src/api/java/mods/railcraft/api/items/IToolCrowbar.java b/src/api/java/mods/railcraft/api/items/IToolCrowbar.java new file mode 100644 index 00000000000..7b8006b5ec2 --- /dev/null +++ b/src/api/java/mods/railcraft/api/items/IToolCrowbar.java @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ + Copyright (c) CovertJaguar, 2011-2020 + + This work (the API) is licensed under the "MIT" License, + see LICENSE.md for details. + -----------------------------------------------------------------------------*/ +package mods.railcraft.api.items; + +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; + +/** + * @author CovertJaguar + */ +public interface IToolCrowbar { + String ORE_TAG = "toolCrowbar"; + + /** + * Controls non-rotational interactions with blocks. Crowbar specific stuff. + *

+ * Rotational interaction is handled by the Block.rotateBlock() function, + * which should be called from the Item.onUseFirst() function of your tool. + * + * @param player the player + * @param crowbar the crowbar + * @param pos the block @return true if can whack a block + */ + boolean canWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos); + + /** + * Callback to do damage to the item. + * + * @param player the player + * @param crowbar the crowbar + * @param pos the block + */ + void onWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos); + + /** + * Controls whether you can link a cart. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart @return true if can link a cart + */ + boolean canLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); + + /** + * Callback to do damage. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart + */ + void onLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); + + /** + * Controls whether you can boost a cart. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart @return true if can boost a cart + */ + boolean canBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); + + /** + * Callback to do damage, boosting a cart usually does more damage than + * normal usage. + * + * @param player the player + * @param crowbar the crowbar + * @param cart the cart + */ + void onBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart); +} diff --git a/src/api/java/mrtjp/projectred/api/IScrewdriver.java b/src/api/java/mrtjp/projectred/api/IScrewdriver.java new file mode 100644 index 00000000000..a6298fecefd --- /dev/null +++ b/src/api/java/mrtjp/projectred/api/IScrewdriver.java @@ -0,0 +1,11 @@ +package mrtjp.projectred.api; + +import net.minecraft.item.ItemStack; +import net.minecraft.entity.player.EntityPlayer; + +public interface IScrewdriver { + + boolean canUse(EntityPlayer player, ItemStack stack); + + void damageScrewdriver(EntityPlayer player, ItemStack stack); // Damage the item on usage +} diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index fa0f424854a..ef4a1730829 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -155,7 +155,9 @@ public class GTValues { MODID_ET = "extratrees", MODID_GENETICS = "genetics", MODID_BOP = "biomesoplenty", - MODID_TCON = "tconstruct"; + MODID_TCON = "tconstruct", + MODID_PROJRED_CORE = "projectred-core", + MODID_RC = "railcraft"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 300c36f537e..4c3ba369341 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -40,6 +40,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.EntityEquipmentSlot; @@ -68,6 +69,8 @@ import forestry.api.arboriculture.IToolGrafter; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import mods.railcraft.api.items.IToolCrowbar; +import mrtjp.projectred.api.IScrewdriver; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,10 +94,12 @@ @Optional.Interface(modid = GTValues.MODID_COFH, iface = "cofh.api.item.IToolHammer"), @Optional.Interface(modid = GTValues.MODID_EIO, iface = "crazypants.enderio.api.tool.ITool"), @Optional.Interface(modid = GTValues.MODID_FR, iface = "forestry.api.arboriculture.IToolGrafter"), + @Optional.Interface(modid = GTValues.MODID_PROJRED_CORE, iface = "mrtjp.projectred.api.IScrewdriver"), + @Optional.Interface(modid = GTValues.MODID_RC, iface = "mods.railcraft.api.items.IToolCrowbar"), @Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") }) public interface IGTTool extends ItemUIFactory, IAEWrench, IToolWrench, IToolHammer, ITool, IToolGrafter, - IOverlayRenderAware { + IOverlayRenderAware, IScrewdriver, IToolCrowbar { /** * @return the modid of the tool @@ -1042,4 +1047,47 @@ default float getSaplingModifier(ItemStack stack, World world, EntityPlayer play default void renderItemOverlayIntoGUI(@NotNull ItemStack stack, int xPosition, int yPosition) { ToolChargeBarRenderer.renderBarsTool(this, stack, xPosition, yPosition); } + + // IScrewdriver + @Override + default boolean canUse(EntityPlayer player, ItemStack stack) { + return get().getToolClasses(stack).contains(ToolClasses.SCREWDRIVER); + } + + @Override + default void damageScrewdriver(EntityPlayer player, ItemStack stack) { + damageItem(stack, player); + } + + // IToolCrowbar + + @Override + default boolean canWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos) { + return get().getToolClasses(crowbar).contains(ToolClasses.CROWBAR); + } + + @Override + default void onWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos) { + damageItem(crowbar, player); + } + + @Override + default boolean canLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + return get().getToolClasses(crowbar).contains(ToolClasses.CROWBAR); + } + + @Override + default void onLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + damageItem(crowbar, player); + } + + @Override + default boolean canBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + return get().getToolClasses(crowbar).contains(ToolClasses.CROWBAR); + } + + @Override + default void onBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart) { + damageItem(crowbar, player); + } } From 4690f2c2393c49c80a9fecea8c22c9e2b5960cd7 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:08:03 -0600 Subject: [PATCH 017/168] Fix silicon bee crash (#2299) --- .../gregtech/integration/forestry/bees/GTBeeDefinition.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 827eb307c28..97fed7a25c3 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -587,7 +587,8 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, TOLERATES_RAIN, true); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Loader.isModLoaded(GTValues.MODID_MB) && Loader.isModLoaded(GTValues.MODID_APPENG)) { + // MB Skystone bee is only registered if AE2 is also active dis.registerMutation(IRON, ForestryUtil.getSpecies(GTValues.MODID_MB, "AESkystone"), 17); } else { dis.registerMutation(IRON, BeeDefinition.IMPERIAL, 17); From 9faa5c06cf1eb82038ca05e328e156bcc624ff83 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:23:26 -0600 Subject: [PATCH 018/168] Fix using MV muffler in EBF JEI preview (#2298) --- .../common/metatileentities/MetaTileEntities.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index a6ff769f8ec..2ab4fcce70c 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -190,7 +190,7 @@ public class MetaTileEntities { // UHV public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, // ZPM, UV - public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV]; // LV-UV + public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; public static final MetaTileEntityQuantumTank[] QUANTUM_TANK = new MetaTileEntityQuantumTank[10]; @@ -1062,12 +1062,13 @@ public static void init() { CLEANING_MAINTENANCE_HATCH = registerMetaTileEntity(1401, new MetaTileEntityCleaningMaintenanceHatch(gregtechId("maintenance_hatch_cleanroom_auto"))); - // Muffler Hatches, IDs 1657- - for (int i = 0; i < MUFFLER_HATCH.length; i++) { - String voltageName = GTValues.VN[i + 1].toLowerCase(); - MUFFLER_HATCH[i] = new MetaTileEntityMufflerHatch(gregtechId("muffler_hatch." + voltageName), i + 1); + // Muffler Hatches, IDs 1657-1664 + for (int i = 0; i < MUFFLER_HATCH.length - 1; i++) { + int tier = i + 1; + String voltageName = GTValues.VN[tier].toLowerCase(); + MUFFLER_HATCH[tier] = new MetaTileEntityMufflerHatch(gregtechId("muffler_hatch." + voltageName), tier); - registerMetaTileEntity(1657 + i, MUFFLER_HATCH[i]); + registerMetaTileEntity(1657 + i, MUFFLER_HATCH[tier]); } CLIPBOARD_TILE = registerMetaTileEntity(1666, new MetaTileEntityClipboard(gregtechId("clipboard"))); From 26a94337f6f7329b1d5d0dd77b591242e794499d Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:26:12 -0700 Subject: [PATCH 019/168] Allow specifying NBT matching on Research ItemStacks (#2294) --- .../builders/AssemblyLineRecipeBuilder.java | 28 ++++++++++++++++ .../builders/ResearchRecipeBuilder.java | 16 +++++++-- .../api/util/AssemblyLineManager.java | 33 ++++++++++++++++--- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java index 2d9d5006c1b..9ddc9d6851b 100644 --- a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java @@ -155,6 +155,7 @@ public static class ResearchRecipeEntry { private final String researchId; private final ItemStack researchStack; private final ItemStack dataStack; + private final boolean ignoreNBT; private final int duration; private final int EUt; private final int CWUt; @@ -166,6 +167,9 @@ public static class ResearchRecipeEntry { * @param duration the duration of the recipe * @param EUt the EUt of the recipe * @param CWUt how much computation per tick this recipe needs if in Research Station + *

+ * By default, will ignore NBT on researchStack input. If NBT matching is desired, see + * {@link #ResearchRecipeEntry(String, ItemStack, ItemStack, boolean, int, int, int)} */ public ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack researchStack, @NotNull ItemStack dataStack, int duration, int EUt, int CWUt) { @@ -175,6 +179,26 @@ public ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack resear this.duration = duration; this.EUt = EUt; this.CWUt = CWUt; + this.ignoreNBT = true; + } + + /** + * @param researchId the id of the research to store + * @param researchStack the stack to scan for research + * @param dataStack the stack to contain the data + * @param duration the duration of the recipe + * @param EUt the EUt of the recipe + * @param CWUt how much computation per tick this recipe needs if in Research Station + */ + public ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack researchStack, + @NotNull ItemStack dataStack, boolean ignoreNBT, int duration, int EUt, int CWUt) { + this.researchId = researchId; + this.researchStack = researchStack; + this.dataStack = dataStack; + this.ignoreNBT = ignoreNBT; + this.duration = duration; + this.EUt = EUt; + this.CWUt = CWUt; } @NotNull @@ -192,6 +216,10 @@ public ItemStack getDataStack() { return dataStack; } + public boolean getIgnoreNBT() { + return ignoreNBT; + } + public int getDuration() { return duration; } diff --git a/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java index bbbda50d520..b20da993e70 100644 --- a/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/ResearchRecipeBuilder.java @@ -15,12 +15,22 @@ public abstract class ResearchRecipeBuilder> protected ItemStack researchStack; protected ItemStack dataStack; + protected boolean ignoreNBT; protected String researchId; protected int eut; public T researchStack(@NotNull ItemStack researchStack) { if (!researchStack.isEmpty()) { this.researchStack = researchStack; + this.ignoreNBT = true; + } + return (T) this; + } + + public T researchStack(@NotNull ItemStack researchStack, boolean ignoreNBT) { + if (!researchStack.isEmpty()) { + this.researchStack = researchStack; + this.ignoreNBT = ignoreNBT; } return (T) this; } @@ -99,7 +109,8 @@ protected AssemblyLineRecipeBuilder.ResearchRecipeEntry build() { validateResearchItem(); if (duration <= 0) duration = DEFAULT_SCANNER_DURATION; if (eut <= 0) eut = DEFAULT_SCANNER_EUT; - return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, duration, + return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, ignoreNBT, + duration, eut, 0); } } @@ -148,7 +159,8 @@ protected AssemblyLineRecipeBuilder.ResearchRecipeEntry build() { int duration = totalCWU; if (eut <= 0) eut = DEFAULT_STATION_EUT; - return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, duration, + return new AssemblyLineRecipeBuilder.ResearchRecipeEntry(researchId, researchStack, dataStack, ignoreNBT, + duration, eut, cwut); } } diff --git a/src/main/java/gregtech/api/util/AssemblyLineManager.java b/src/main/java/gregtech/api/util/AssemblyLineManager.java index f4f577996b2..a2652acfa84 100644 --- a/src/main/java/gregtech/api/util/AssemblyLineManager.java +++ b/src/main/java/gregtech/api/util/AssemblyLineManager.java @@ -121,33 +121,56 @@ public static void createDefaultResearchRecipe(@NotNull AssemblyLineRecipeBuilde for (AssemblyLineRecipeBuilder.ResearchRecipeEntry entry : builder.getRecipeEntries()) { createDefaultResearchRecipe(entry.getResearchId(), entry.getResearchStack(), entry.getDataStack(), + entry.getIgnoreNBT(), entry.getDuration(), entry.getEUt(), entry.getCWUt()); } } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void createDefaultResearchRecipe(@NotNull String researchId, @NotNull ItemStack researchItem, @NotNull ItemStack dataItem, int duration, int EUt, int CWUt) { + createDefaultResearchRecipe(researchId, researchItem, dataItem, true, duration, EUt, CWUt); + } + + public static void createDefaultResearchRecipe(@NotNull String researchId, @NotNull ItemStack researchItem, + @NotNull ItemStack dataItem, boolean ignoreNBT, int duration, + int EUt, int CWUt) { if (!ConfigHolder.machines.enableResearch) return; NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(dataItem); writeResearchToNBT(compound, researchId); if (CWUt > 0) { - RecipeMaps.RESEARCH_STATION_RECIPES.recipeBuilder() + RecipeBuilder researchBuilder = RecipeMaps.RESEARCH_STATION_RECIPES.recipeBuilder() .inputNBT(dataItem.getItem(), 1, dataItem.getMetadata(), NBTMatcher.ANY, NBTCondition.ANY) - .inputs(researchItem) .outputs(dataItem) .EUt(EUt) .CWUt(CWUt) - .totalCWU(duration) - .buildAndRegister(); + .totalCWU(duration); + + if (ignoreNBT) { + researchBuilder.inputNBT(researchItem.getItem(), 1, researchItem.getMetadata(), NBTMatcher.ANY, + NBTCondition.ANY); + } else { + researchBuilder.inputs(researchItem); + } + + researchBuilder.buildAndRegister(); } else { RecipeBuilder builder = RecipeMaps.SCANNER_RECIPES.recipeBuilder() .inputNBT(dataItem.getItem(), 1, dataItem.getMetadata(), NBTMatcher.ANY, NBTCondition.ANY) - .inputs(researchItem) .outputs(dataItem) .duration(duration) .EUt(EUt); + + if (ignoreNBT) { + builder.inputNBT(researchItem.getItem(), 1, researchItem.getMetadata(), NBTMatcher.ANY, + NBTCondition.ANY); + } else { + builder.inputs(researchItem); + } + builder.applyProperty(ScanProperty.getInstance(), true); builder.buildAndRegister(); } From b1f050b78ea8b4c64939d00073f9c6cdc054347b Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:27:14 -0700 Subject: [PATCH 020/168] Attempt to clarify tooltip (#2300) --- src/main/resources/assets/gregtech/lang/en_us.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 38f6999c437..531dfc20c6a 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5560,7 +5560,7 @@ gregtech.multiblock.pattern.error.batteries=§cMust have at least one non-empty gregtech.multiblock.pattern.error.filters=§cAll filters must be the same§r gregtech.multiblock.pattern.clear_amount_1=§6Must have a clear 1x1x1 space in front§r gregtech.multiblock.pattern.clear_amount_3=§6Must have a clear 3x3x1 space in front§r -gregtech.multiblock.pattern.single=§6Only this block can be used§r +gregtech.multiblock.pattern.single=§6Only this block type can be used§r gregtech.multiblock.pattern.location_end=§cVery End§r gregtech.multiblock.pattern.replaceable_air=Replaceable by Air From 432269522c323d2844630174576ce674e2cba29d Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:42:46 -0600 Subject: [PATCH 021/168] Chisel module (#2290) --- dependencies.gradle | 1 + src/main/java/gregtech/api/GTValues.java | 3 +- .../api/unification/ore/OrePrefix.java | 1 + .../integration/chisel/ChiselModule.java | 119 ++++++++++++++++++ .../gregtech/loaders/OreDictionaryLoader.java | 2 + .../gregtech/modules/GregTechModules.java | 1 + 6 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/main/java/gregtech/integration/chisel/ChiselModule.java diff --git a/dependencies.gradle b/dependencies.gradle index 3af530e782d..19b3de56f63 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,6 +41,7 @@ dependencies { compileOnlyApi rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 compileOnlyApi rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 + compileOnlyApi rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index ef4a1730829..7a1b5d34f4f 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -157,7 +157,8 @@ public class GTValues { MODID_BOP = "biomesoplenty", MODID_TCON = "tconstruct", MODID_PROJRED_CORE = "projectred-core", - MODID_RC = "railcraft"; + MODID_RC = "railcraft", + MODID_CHISEL = "chisel"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/unification/ore/OrePrefix.java b/src/main/java/gregtech/api/unification/ore/OrePrefix.java index 64eb11cd7fa..30239988324 100644 --- a/src/main/java/gregtech/api/unification/ore/OrePrefix.java +++ b/src/main/java/gregtech/api/unification/ore/OrePrefix.java @@ -467,6 +467,7 @@ public static void init() { block.modifyMaterialAmount(Materials.Glowstone, 4); block.modifyMaterialAmount(Materials.NetherQuartz, 4); + block.modifyMaterialAmount(Materials.CertusQuartz, 4); block.modifyMaterialAmount(Materials.Brick, 4); block.modifyMaterialAmount(Materials.Clay, 4); block.modifyMaterialAmount(Materials.Glass, 1); diff --git a/src/main/java/gregtech/integration/chisel/ChiselModule.java b/src/main/java/gregtech/integration/chisel/ChiselModule.java new file mode 100644 index 00000000000..c6dc3cafe05 --- /dev/null +++ b/src/main/java/gregtech/integration/chisel/ChiselModule.java @@ -0,0 +1,119 @@ +package gregtech.integration.chisel; + +import gregtech.api.GTValues; +import gregtech.api.block.VariantBlock; +import gregtech.api.modules.GregTechModule; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.Materials; +import gregtech.common.blocks.BlockColored; +import gregtech.common.blocks.BlockCompressed; +import gregtech.common.blocks.BlockWarningSign; +import gregtech.common.blocks.BlockWarningSign1; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.blocks.StoneVariantBlock; +import gregtech.common.blocks.StoneVariantBlock.StoneType; +import gregtech.common.blocks.StoneVariantBlock.StoneVariant; +import gregtech.common.blocks.wood.BlockGregPlanks; +import gregtech.integration.IntegrationSubmodule; +import gregtech.modules.GregTechModules; + +import net.minecraft.block.Block; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IStringSerializable; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLInterModComms; + +import team.chisel.common.carving.Carving; + +import java.util.Objects; + +@GregTechModule( + moduleID = GregTechModules.MODULE_CHISEL, + containerID = GTValues.MODID, + modDependencies = GTValues.MODID_CHISEL, + name = "GregTech Chisel Integration", + description = "Chisel Integration Module") +public class ChiselModule extends IntegrationSubmodule { + + @Override + public void init(FMLInitializationEvent event) { + // GT custom groups + addVariations("gt_warning_sign", MetaBlocks.WARNING_SIGN, BlockWarningSign.SignType.values()); + addVariations("gt_warning_sign", MetaBlocks.WARNING_SIGN_1, BlockWarningSign1.SignType.values()); + addVariations("gt_studs", MetaBlocks.STUDS); + addVariations("gt_metal_sheet", MetaBlocks.METAL_SHEET); + addVariations("gt_large_metal_sheet", MetaBlocks.LARGE_METAL_SHEET); + for (EnumDyeColor color : EnumDyeColor.values()) { + Block lamp = MetaBlocks.LAMPS.get(color); + Block lampBorderless = MetaBlocks.BORDERLESS_LAMPS.get(color); + String group = "gt_lamp_" + color.getName().toLowerCase(); + for (int i = 0; i < 8; i++) { + addVariation(group, lamp, i); + addVariation(group, lampBorderless, i); + } + } + + // Chisel shared groups + addVariations("marble", StoneType.MARBLE, false); + addVariations("basalt", StoneType.BASALT, false); + addVariations("black_granite", StoneType.BLACK_GRANITE, false); + addVariations("red_granite", StoneType.RED_GRANITE, false); + addVariations("light_concrete", StoneType.CONCRETE_LIGHT, true); + addVariations("dark_concrete", StoneType.CONCRETE_DARK, true); + + // Mod-dependent groups + if (doesGroupExist("treated_wood")) { // IE Treated Wood group + addVariations("treated_wood", MetaBlocks.PLANKS, BlockGregPlanks.BlockType.TREATED_PLANK); + } + if (doesGroupExist("certus")) { // AE2 Certus Quartz group + addVariation("certus", Materials.CertusQuartz); + } + } + + @SafeVarargs + private & IStringSerializable, T extends VariantBlock> void addVariations(String group, + T block, + U... variants) { + if (variants != null) { + for (U variant : variants) { + addVariation(group, block, block.getMetaFromState(block.getState(variant))); + } + } + } + + private void addVariations(String group, BlockColored block) { + for (EnumDyeColor color : EnumDyeColor.values()) { + addVariation(group, block, color.getMetadata()); + } + } + + private void addVariations(String group, StoneType type, boolean enableCobbles) { + for (StoneVariantBlock.StoneVariant variant : StoneVariant.values()) { + if (!enableCobbles && (variant == StoneVariant.COBBLE || variant == StoneVariant.COBBLE_MOSSY)) { + continue; + } + StoneVariantBlock block = MetaBlocks.STONE_BLOCKS.get(variant); + int meta = block.getMetaFromState(block.getState(type)); + addVariation(group, block, meta); + } + } + + private void addVariation(String group, Material material) { + BlockCompressed block = MetaBlocks.COMPRESSED.get(material); + int meta = block.getMetaFromState(block.getBlock(material)); + addVariation(group, block, meta); + } + + private void addVariation(String group, Block block, int meta) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setString("group", group); + tag.setString("block", Objects.requireNonNull(block.getRegistryName()).toString()); + tag.setInteger("meta", meta); + FMLInterModComms.sendMessage(GTValues.MODID_CHISEL, "add_variation", tag); + } + + private boolean doesGroupExist(String group) { + return Carving.chisel.getGroup(group) != null; + } +} diff --git a/src/main/java/gregtech/loaders/OreDictionaryLoader.java b/src/main/java/gregtech/loaders/OreDictionaryLoader.java index b05fba4609b..a902983af39 100644 --- a/src/main/java/gregtech/loaders/OreDictionaryLoader.java +++ b/src/main/java/gregtech/loaders/OreDictionaryLoader.java @@ -25,12 +25,14 @@ public class OreDictionaryLoader { public static final String OREDICT_FUEL_COKE = "fuelCoke"; public static final String OREDICT_BLOCK_FUEL_COKE = "blockFuelCoke"; + public static final String OREDICT_BLOCK_COAL_COKE = "blockCoalCoke"; public static void init() { GTLog.logger.info("Registering OreDict entries."); OreDictionary.registerOre(OREDICT_FUEL_COKE, OreDictUnifier.get(OrePrefix.gem, Materials.Coke)); OreDictionary.registerOre(OREDICT_BLOCK_FUEL_COKE, OreDictUnifier.get(OrePrefix.block, Materials.Coke)); + OreDictionary.registerOre(OREDICT_BLOCK_COAL_COKE, OreDictUnifier.get(OrePrefix.block, Materials.Coke)); OreDictionary.registerOre("crystalCertusQuartz", OreDictUnifier.get(OrePrefix.gem, Materials.CertusQuartz)); OreDictUnifier.registerOre(new ItemStack(Blocks.CLAY), OrePrefix.block, Materials.Clay); diff --git a/src/main/java/gregtech/modules/GregTechModules.java b/src/main/java/gregtech/modules/GregTechModules.java index 9c07e90db26..96ad33664b9 100644 --- a/src/main/java/gregtech/modules/GregTechModules.java +++ b/src/main/java/gregtech/modules/GregTechModules.java @@ -17,6 +17,7 @@ public class GregTechModules implements IModuleContainer { public static final String MODULE_HWYLA = "hwyla_integration"; public static final String MODULE_BAUBLES = "baubles_integration"; public static final String MODULE_FR = "fr_integration"; + public static final String MODULE_CHISEL = "chisel_integration"; @Override public String getID() { From 46b30c72b5e2f9bffbd6697df1f23dbaeb22820d Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:12:42 -0600 Subject: [PATCH 022/168] Fix pipe restrictor render on bottom face (#2302) --- src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java index 841d230d0f5..632bdad8f2b 100644 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java @@ -100,7 +100,7 @@ public static void initializeRestrictor(TextureMap map) { static { FACE_BORDER_MAP.put(EnumFacing.DOWN, - borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST)); + borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST)); FACE_BORDER_MAP.put(EnumFacing.UP, borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST)); FACE_BORDER_MAP.put(EnumFacing.NORTH, From 025d4696495fecbb0f45ba632231f4f5ebb7363d Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:15:58 -0600 Subject: [PATCH 023/168] Fix battery slot charge flickering (#2305) --- .../api/capability/impl/EnergyContainerHandler.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java b/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java index 81972c3f5d7..37688a4deec 100644 --- a/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java +++ b/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java @@ -157,16 +157,16 @@ private boolean handleElectricItem(IElectricItem electricItem) { // Check if the item is a battery (or similar), and if we can receive some amount of energy if (electricItem.canProvideChargeExternally() && getEnergyCanBeInserted() > 0) { - // Drain from the battery if we are below half energy capacity, and if the tier matches - if (chargePercent <= 0.5 && chargeTier == machineTier) { + // Drain from the battery if we are below 1/3rd energy capacity, and if the tier matches + if (chargePercent <= 0.33 && chargeTier == machineTier) { long dischargedBy = electricItem.discharge(getEnergyCanBeInserted(), machineTier, false, true, false); addEnergy(dischargedBy); return dischargedBy > 0L; } } - // Else, check if we have above 50% power - if (chargePercent > 0.5) { + // Else, check if we have above 2/3rds charge + if (chargePercent > 0.66) { long chargedBy = electricItem.charge(getEnergyStored(), chargeTier, false, false); removeEnergy(chargedBy); return chargedBy > 0; @@ -178,7 +178,7 @@ private boolean handleForgeEnergyItem(IEnergyStorage energyStorage) { int machineTier = GTUtility.getTierByVoltage(Math.max(getInputVoltage(), getOutputVoltage())); double chargePercent = getEnergyStored() / (getEnergyCapacity() * 1.0); - if (chargePercent > 0.5) { + if (chargePercent > 0.66) { // 2/3rds full long chargedBy = FeCompat.insertEu(energyStorage, GTValues.V[machineTier]); removeEnergy(chargedBy); return chargedBy > 0; From d2d4420fe414b4147075baeff5239a6e0226457f Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:21:29 -0600 Subject: [PATCH 024/168] Tweak muffler effect API (#2286) --- .../multiblock/MultiblockWithDisplayBase.java | 7 ++- .../particle/VanillaParticleEffects.java | 63 ++++++++++--------- .../MetaTileEntityMufflerHatch.java | 10 ++- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java index a94c78ccdff..55723ef456d 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java @@ -275,7 +275,7 @@ public boolean isMufflerFaceFree() { } /** - * @deprecated Use {@link gregtech.client.particle.VanillaParticleEffects#MUFFLER_SMOKE} instead. + * @deprecated Override {@link #getMufflerParticle()} instead. */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -284,6 +284,11 @@ public void runMufflerEffect(float xPos, float yPos, float zPos, float xSpd, flo getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, xSpd, ySpd, zSpd); } + @SideOnly(Side.CLIENT) + public @NotNull EnumParticleTypes getMufflerParticle() { + return EnumParticleTypes.SMOKE_LARGE; + } + /** * Sets the recovery items of this multiblock * diff --git a/src/main/java/gregtech/client/particle/VanillaParticleEffects.java b/src/main/java/gregtech/client/particle/VanillaParticleEffects.java index 2765d3945d9..ddfa0592369 100644 --- a/src/main/java/gregtech/client/particle/VanillaParticleEffects.java +++ b/src/main/java/gregtech/client/particle/VanillaParticleEffects.java @@ -26,35 +26,6 @@ public enum VanillaParticleEffects implements IMachineParticleEffect { mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x, y, z, 0, 0, 0); }), - MUFFLER_SMOKE(mte -> { - if (mte.getWorld() == null || mte.getPos() == null) return; - - BlockPos pos = mte.getPos(); - EnumFacing facing = mte.getFrontFacing(); - float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.25F; - float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; - float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.25F; - - float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); - float xSpd; - float zSpd; - - if (facing.getYOffset() == -1) { - float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; - xSpd = (float) Math.sin(temp) * 0.1F; - zSpd = (float) Math.cos(temp) * 0.1F; - } else { - xSpd = facing.getXOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); - zSpd = facing.getZOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); - } - - xPos += GTValues.RNG.nextFloat() * 0.5F; - yPos += GTValues.RNG.nextFloat() * 0.5F; - zPos += GTValues.RNG.nextFloat() * 0.5F; - - mte.getWorld().spawnParticle(EnumParticleTypes.SMOKE_LARGE, xPos, yPos, zPos, xSpd, ySpd, zSpd); - }), - PBF_SMOKE(mte -> { if (mte.getWorld() == null || mte.getPos() == null) return; @@ -167,12 +138,12 @@ public void runEffect(@NotNull MetaTileEntity metaTileEntity) { } @SideOnly(Side.CLIENT) - public static void defaultFrontEffect(MetaTileEntity mte, EnumParticleTypes... particles) { + public static void defaultFrontEffect(@NotNull MetaTileEntity mte, EnumParticleTypes... particles) { defaultFrontEffect(mte, 0.0F, particles); } @SideOnly(Side.CLIENT) - public static void defaultFrontEffect(MetaTileEntity mte, float yOffset, EnumParticleTypes... particles) { + public static void defaultFrontEffect(@NotNull MetaTileEntity mte, float yOffset, EnumParticleTypes... particles) { if (particles == null || particles.length == 0) return; if (mte.getWorld() == null || mte.getPos() == null) return; @@ -201,4 +172,34 @@ public static void defaultFrontEffect(MetaTileEntity mte, float yOffset, EnumPar mte.getWorld().spawnParticle(particle, x, y, z, 0, 0, 0); } } + + @SideOnly(Side.CLIENT) + public static void mufflerEffect(@NotNull MetaTileEntity mte, @NotNull EnumParticleTypes particle) { + if (mte.getWorld() == null || mte.getPos() == null) return; + + BlockPos pos = mte.getPos(); + EnumFacing facing = mte.getFrontFacing(); + float xPos = facing.getXOffset() * 0.76F + pos.getX() + 0.25F; + float yPos = facing.getYOffset() * 0.76F + pos.getY() + 0.25F; + float zPos = facing.getZOffset() * 0.76F + pos.getZ() + 0.25F; + + float ySpd = facing.getYOffset() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); + float xSpd; + float zSpd; + + if (facing.getYOffset() == -1) { + float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; + xSpd = (float) Math.sin(temp) * 0.1F; + zSpd = (float) Math.cos(temp) * 0.1F; + } else { + xSpd = facing.getXOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); + zSpd = facing.getZOffset() * (0.1F + 0.2F * GTValues.RNG.nextFloat()); + } + + xPos += GTValues.RNG.nextFloat() * 0.5F; + yPos += GTValues.RNG.nextFloat() * 0.5F; + zPos += GTValues.RNG.nextFloat() * 0.5F; + + mte.getWorld().spawnParticle(particle, xPos, yPos, zPos, xSpd, ySpd, zSpd); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index 4b3e75a4c2c..5bc07d2e793 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -11,6 +11,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -69,7 +70,7 @@ public void update() { if (getWorld().isRemote && getController() instanceof MultiblockWithDisplayBase controller && controller.isActive()) { - VanillaParticleEffects.MUFFLER_SMOKE.runEffect(this); + VanillaParticleEffects.mufflerEffect(this, controller.getMufflerParticle()); } } @@ -112,12 +113,15 @@ private boolean checkFrontFaceFree() { return blockState.getBlock().isAir(blockState, getWorld(), frontPos) || GTUtility.isBlockSnow(blockState); } - /** @deprecated Use {@link VanillaParticleEffects#MUFFLER_SMOKE} instead. */ + /** @deprecated No longer needed. Multiblock controller sets the particle type. */ @Deprecated @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @SideOnly(Side.CLIENT) public void pollutionParticles() { - VanillaParticleEffects.MUFFLER_SMOKE.runEffect(this); + MultiblockControllerBase controller = getController(); + if (controller instanceof MultiblockWithDisplayBase displayBase) { + VanillaParticleEffects.mufflerEffect(this, displayBase.getMufflerParticle()); + } } @Override From c86e1165fa52433b3c4aac73f7c4ab7686d7a867 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Fri, 15 Dec 2023 21:22:02 -0500 Subject: [PATCH 025/168] log incomplete packet reads in NetworkHandler (#2288) --- .../core/network/internal/NetworkHandler.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/core/network/internal/NetworkHandler.java b/src/main/java/gregtech/core/network/internal/NetworkHandler.java index 60849c35415..3d6769891f9 100644 --- a/src/main/java/gregtech/core/network/internal/NetworkHandler.java +++ b/src/main/java/gregtech/core/network/internal/NetworkHandler.java @@ -7,6 +7,7 @@ import gregtech.api.network.INetworkHandler; import gregtech.api.network.IPacket; import gregtech.api.network.IServerExecutor; +import gregtech.api.util.GTLog; import gregtech.core.CoreModule; import net.minecraft.client.network.NetHandlerPlayClient; @@ -26,8 +27,11 @@ import net.minecraftforge.fml.relauncher.SideOnly; import io.netty.buffer.Unpooled; +import org.jetbrains.annotations.NotNull; -public class NetworkHandler implements INetworkHandler { +import java.lang.reflect.InvocationTargetException; + +public final class NetworkHandler implements INetworkHandler { private static final NetworkHandler INSTANCE = new NetworkHandler(); @@ -106,7 +110,7 @@ public void sendToServer(IPacket packet) { @SubscribeEvent @SideOnly(Side.CLIENT) - public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) throws Exception { + public void onClientPacket(FMLNetworkEvent.@NotNull ClientCustomPacketEvent event) throws Exception { IPacket packet = toGTPacket(event.getPacket()); if (IClientExecutor.class.isAssignableFrom(packet.getClass())) { IClientExecutor executor = (IClientExecutor) packet; @@ -121,7 +125,7 @@ public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) throws } @SubscribeEvent - public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) throws Exception { + public void onServerPacket(FMLNetworkEvent.@NotNull ServerCustomPacketEvent event) throws Exception { IPacket packet = toGTPacket(event.getPacket()); if (IServerExecutor.class.isAssignableFrom(packet.getClass())) { IServerExecutor executor = (IServerExecutor) packet; @@ -135,17 +139,27 @@ public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) throws } } - private FMLProxyPacket toFMLPacket(IPacket packet) { + private @NotNull FMLProxyPacket toFMLPacket(@NotNull IPacket packet) { PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); buf.writeVarInt(packetHandler.getPacketId(packet.getClass())); packet.encode(buf); return new FMLProxyPacket(buf, GTValues.MODID); } - private IPacket toGTPacket(FMLProxyPacket proxyPacket) throws Exception { + private @NotNull IPacket toGTPacket(@NotNull FMLProxyPacket proxyPacket) throws NoSuchMethodException, + InvocationTargetException, + InstantiationException, + IllegalAccessException { PacketBuffer payload = (PacketBuffer) proxyPacket.payload(); - IPacket packet = packetHandler.getPacketClass(payload.readVarInt()).newInstance(); + var clazz = packetHandler.getPacketClass(payload.readVarInt()); + IPacket packet = clazz.getConstructor().newInstance(); packet.decode(payload); + + if (payload.readableBytes() != 0) { + GTLog.logger.error( + "NetworkHandler failed to finish reading packet with class {} and {} bytes remaining", + clazz.getName(), payload.readableBytes()); + } return packet; } } From d58a335e7d44c500bc28a9559d71f81cd2d51710 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:32:41 -0600 Subject: [PATCH 026/168] Fusion rebalancing (#2252) --- .../capability/impl/AbstractRecipeLogic.java | 3 +- .../impl/MultiblockRecipeLogic.java | 2 +- .../FusionEUToStartProperty.java | 19 ++++++---- .../material/materials/ElementMaterials.java | 2 ++ .../java/gregtech/common/CommonProxy.java | 6 ++-- .../electric/MetaTileEntityFusionReactor.java | 14 ++++++++ .../gregtech/loaders/recipe/FuelRecipes.java | 14 ++++++++ .../gregtech/loaders/recipe/FusionLoader.java | 36 ++++++++++++++----- 8 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index a241b32b3a0..cc2ce878aee 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -651,8 +651,7 @@ protected int[] calculateOverclock(@NotNull Recipe recipe) { * @param recipe the recipe to overclock * @return an int array of {OverclockedEUt, OverclockedDuration} */ - @NotNull - protected int[] performOverclocking(@NotNull Recipe recipe) { + protected int @NotNull [] performOverclocking(@NotNull Recipe recipe) { int[] values = { recipe.getEUt(), recipe.getDuration(), getNumberOfOCs(recipe.getEUt()) }; modifyOverclockPre(values, recipe.getRecipePropertyStorage()); diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 3917d4a7bda..1ebb3e73c82 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -282,7 +282,7 @@ protected boolean prepareRecipeDistinct(Recipe recipe) { } @Override - protected void modifyOverclockPre(@NotNull int[] values, @NotNull IRecipePropertyStorage storage) { + protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipePropertyStorage storage) { super.modifyOverclockPre(values, storage); // apply maintenance bonuses diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java index 12fd90e7748..60188d8cd5f 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java @@ -6,6 +6,7 @@ import net.minecraft.client.resources.I18n; import org.apache.commons.lang3.Validate; +import org.apache.commons.lang3.tuple.Pair; import java.util.Map; import java.util.TreeMap; @@ -14,7 +15,7 @@ public class FusionEUToStartProperty extends RecipeProperty { public static final String KEY = "eu_to_start"; - private static final TreeMap registeredFusionTiers = new TreeMap<>(); + private static final TreeMap> registeredFusionTiers = new TreeMap<>(); private static FusionEUToStartProperty INSTANCE; @@ -33,23 +34,29 @@ public static FusionEUToStartProperty getInstance() { @Override public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.eu_to_start", - TextFormattingUtil.formatLongToCompactString(castValue(value))) + getFusionTier(castValue(value)), x, y, + TextFormattingUtil.formatLongToCompactString(castValue(value))) + getFusionTierName(castValue(value)), + x, y, color); } - private static String getFusionTier(Long eu) { - Map.Entry mapEntry = registeredFusionTiers.ceilingEntry(eu); + private static String getFusionTierName(Long eu) { + Map.Entry> mapEntry = registeredFusionTiers.ceilingEntry(eu); if (mapEntry == null) { throw new IllegalArgumentException("Value is above registered maximum EU values"); } - return String.format(" %s", mapEntry.getValue()); + return String.format(" %s", mapEntry.getValue().getRight()); + } + + public static int getFusionTier(Long eu) { + Map.Entry> mapEntry = registeredFusionTiers.ceilingEntry(eu); + return mapEntry == null ? 0 : mapEntry.getValue().getLeft(); } public static void registerFusionTier(int tier, String shortName) { Validate.notNull(shortName); long maxEU = 16 * 10000000L * (long) Math.pow(2, tier - 6); - registeredFusionTiers.put(maxEU, shortName); + registeredFusionTiers.put(maxEU, Pair.of(tier, shortName)); } } diff --git a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java index 37c745dc5c5..8d4af1f4fa7 100644 --- a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java @@ -42,6 +42,7 @@ public static void register() { Americium = new Material.Builder(3, gregtechId("americium")) .ingot(3) .liquid(new FluidBuilder().temperature(1449)) + .plasma() .color(0x287869).iconSet(METALLIC) .flags(EXT_METAL, GENERATE_FOIL, GENERATE_FINE_WIRE, GENERATE_DOUBLE_PLATE) .element(Elements.Am) @@ -814,6 +815,7 @@ public static void register() { Tin = new Material.Builder(112, gregtechId("tin")) .ingot(1) .liquid(new FluidBuilder().temperature(505)) + .plasma() .ore() .color(0xDCDCDC) .flags(EXT2_METAL, MORTAR_GRINDABLE, GENERATE_ROTOR, GENERATE_SPRING, GENERATE_SPRING_SMALL, diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index 7cac0f93204..f8a956e201b 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -297,9 +297,9 @@ public static void initComponents(RegistryEvent.Register event) { @SubscribeEvent public static void registerRecipes(RegistryEvent.Register event) { // Registers Fusion tiers for the FusionEUToStartProperty - FusionEUToStartProperty.registerFusionTier(6, "(MK1)"); - FusionEUToStartProperty.registerFusionTier(7, "(MK2)"); - FusionEUToStartProperty.registerFusionTier(8, "(MK3)"); + FusionEUToStartProperty.registerFusionTier(GTValues.LuV, "(MK1)"); + FusionEUToStartProperty.registerFusionTier(GTValues.ZPM, "(MK2)"); + FusionEUToStartProperty.registerFusionTier(GTValues.UV, "(MK3)"); // Register data stick copying custom scanner logic AssemblyLineManager.registerScannerLogic(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 8e667bedfcb..90b8b70886c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -30,6 +30,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.recipeproperties.FusionEUToStartProperty; +import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -630,6 +631,19 @@ public boolean checkRecipe(@NotNull Recipe recipe) { return true; } + @Override + protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipePropertyStorage storage) { + super.modifyOverclockPre(values, storage); + + // Limit the number of OCs to the difference in fusion reactor MK. + // I.e., a MK2 reactor can overclock a MK1 recipe once, and a + // MK3 reactor can overclock a MK2 recipe once, or a MK1 recipe twice. + long euToStart = storage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); + int fusionTier = FusionEUToStartProperty.getFusionTier(euToStart); + if (fusionTier != 0) fusionTier -= MetaTileEntityFusionReactor.this.tier; + values[2] = Math.min(fusionTier, values[2]); + } + @NotNull @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/loaders/recipe/FuelRecipes.java b/src/main/java/gregtech/loaders/recipe/FuelRecipes.java index 94da5ecb799..740521e8657 100644 --- a/src/main/java/gregtech/loaders/recipe/FuelRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/FuelRecipes.java @@ -291,6 +291,13 @@ public static void registerFuels() { RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Iron.getPlasma(1)) .fluidOutputs(Iron.getFluid(1)) + .duration(112) + .EUt((int) V[EV]) + .buildAndRegister(); + + RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() + .fluidInputs(Tin.getPlasma(1)) + .fluidOutputs(Tin.getFluid(1)) .duration(128) .EUt((int) V[EV]) .buildAndRegister(); @@ -301,5 +308,12 @@ public static void registerFuels() { .duration(192) .EUt((int) V[EV]) .buildAndRegister(); + + RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() + .fluidInputs(Americium.getPlasma(1)) + .fluidOutputs(Americium.getFluid(1)) + .duration(320) + .EUt((int) V[EV]) + .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/FusionLoader.java b/src/main/java/gregtech/loaders/recipe/FusionLoader.java index f5ec3a7b861..49515136876 100644 --- a/src/main/java/gregtech/loaders/recipe/FusionLoader.java +++ b/src/main/java/gregtech/loaders/recipe/FusionLoader.java @@ -38,16 +38,16 @@ public static void init() { RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Silicon.getFluid(16)) .fluidInputs(Materials.Magnesium.getFluid(16)) - .fluidOutputs(Materials.Iron.getPlasma(16)) + .fluidOutputs(Materials.Iron.getPlasma(144)) .duration(32) .EUt(VA[IV]) - .EUToStart(360_000_000) + .EUToStart(300_000_000) .buildAndRegister(); RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Potassium.getFluid(16)) .fluidInputs(Materials.Fluorine.getFluid(125)) - .fluidOutputs(Materials.Nickel.getPlasma(16)) + .fluidOutputs(Materials.Nickel.getPlasma(144)) .duration(16) .EUt(VA[LuV]) .EUToStart(480_000_000) @@ -62,6 +62,24 @@ public static void init() { .EUToStart(180_000_000) .buildAndRegister(); + RecipeMaps.FUSION_RECIPES.recipeBuilder() + .fluidInputs(Materials.Plutonium241.getFluid(144)) + .fluidInputs(Materials.Hydrogen.getFluid(2000)) + .fluidOutputs(Materials.Americium.getPlasma(144)) + .duration(64) + .EUt(98304) + .EUToStart(500_000_000) + .buildAndRegister(); + + RecipeMaps.FUSION_RECIPES.recipeBuilder() + .fluidInputs(Materials.Silver.getFluid(144)) + .fluidInputs(Materials.Helium3.getFluid(375)) + .fluidOutputs(Materials.Tin.getPlasma(144)) + .duration(16) + .EUt(49152) + .EUToStart(280_000_000) + .buildAndRegister(); + RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Neodymium.getFluid(16)) .fluidInputs(Materials.Hydrogen.getFluid(375)) @@ -72,9 +90,9 @@ public static void init() { .buildAndRegister(); RecipeMaps.FUSION_RECIPES.recipeBuilder() - .fluidInputs(Materials.Lutetium.getFluid(32)) - .fluidInputs(Materials.Chrome.getFluid(32)) - .fluidOutputs(Materials.Americium.getFluid(32)) + .fluidInputs(Materials.Lutetium.getFluid(16)) + .fluidInputs(Materials.Chrome.getFluid(16)) + .fluidOutputs(Materials.Americium.getFluid(16)) .duration(64) .EUt(49152) .EUToStart(200_000_000) @@ -147,16 +165,16 @@ public static void init() { .fluidInputs(Materials.Gallium.getFluid(16)) .fluidInputs(Materials.Radon.getFluid(125)) .fluidOutputs(Materials.Duranium.getFluid(16)) - .duration(64) + .duration(32) .EUt(16384) .EUToStart(140_000_000) .buildAndRegister(); RecipeMaps.FUSION_RECIPES.recipeBuilder() - .fluidInputs(Materials.Titanium.getFluid(32)) + .fluidInputs(Materials.Titanium.getFluid(48)) .fluidInputs(Materials.Duranium.getFluid(32)) .fluidOutputs(Materials.Tritanium.getFluid(16)) - .duration(64) + .duration(16) .EUt(VA[LuV]) .EUToStart(200_000_000) .buildAndRegister(); From 8f43bf1a754cc4acb82888f8dc7da54b3c30207f Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 17 Dec 2023 03:07:07 -0600 Subject: [PATCH 027/168] Fix plasma temp NPE for plasma-only materials (#2306) --- .../java/gregtech/api/fluids/FluidBuilder.java | 2 +- .../gregtech/api/fluids/store/FluidStorage.java | 15 +++++++++------ .../api/fluids/store/FluidStorageKey.java | 17 +++++++++++++++++ .../api/fluids/store/FluidStorageKeys.java | 2 +- .../loaders/recipe/RecyclingRecipes.java | 10 +++++++--- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index 757369b75ae..f7a75111cc4 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -428,7 +428,7 @@ private void determineTemperature(@Nullable Material material) { } case GAS -> ROOM_TEMPERATURE; case PLASMA -> { - if (material.hasFluid()) { + if (material.hasFluid() && material.getFluid() != null) { yield BASE_PLASMA_TEMPERATURE + material.getFluid().getTemperature(); } yield BASE_PLASMA_TEMPERATURE; diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorage.java b/src/main/java/gregtech/api/fluids/store/FluidStorage.java index f9a232b0d27..fe7505423d0 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorage.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorage.java @@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Comparator; import java.util.Map; public final class FluidStorage { @@ -69,12 +70,14 @@ public void registerFluids(@NotNull Material material) { enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); } - for (var entry : toRegister.entrySet()) { - Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); - if (!storeNoOverwrites(entry.getKey(), fluid)) { - GTLog.logger.error("{} already has an associated fluid for material {}", material); - } - } + toRegister.entrySet().stream() + .sorted(Comparator.comparingInt(e -> -e.getKey().getRegistrationPriority())) + .forEach(entry -> { + Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); + if (!storeNoOverwrites(entry.getKey(), fluid)) { + GTLog.logger.error("{} already has an associated fluid for material {}", material); + } + }); toRegister = null; registered = true; } diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java index 01f44dcc8da..7b58514aa35 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java @@ -24,6 +24,7 @@ public final class FluidStorageKey { private final Function translationKeyFunction; private final int hashCode; private final FluidState defaultFluidState; + private final int registrationPriority; public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, @NotNull UnaryOperator<@NotNull String> registryNameOperator, @@ -35,12 +36,20 @@ public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull Mate @NotNull UnaryOperator<@NotNull String> registryNameOperator, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, @Nullable FluidState defaultFluidState) { + this(resourceLocation, iconType, registryNameOperator, translationKeyFunction, defaultFluidState, 0); + } + + public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, + @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, + @Nullable FluidState defaultFluidState, int registrationPriority) { this.resourceLocation = resourceLocation; this.iconType = iconType; this.registryNameOperator = registryNameOperator; this.translationKeyFunction = translationKeyFunction; this.hashCode = resourceLocation.hashCode(); this.defaultFluidState = defaultFluidState; + this.registrationPriority = registrationPriority; if (keys.containsKey(resourceLocation)) { throw new IllegalArgumentException("Cannot create duplicate keys"); } @@ -81,6 +90,14 @@ public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull Mate return defaultFluidState; } + /** + * @return The registration priority for this fluid type, determining the build order for fluids. + * Useful for when your fluid building requires some properties from previous fluids. + */ + public int getRegistrationPriority() { + return registrationPriority; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java index 10407e03b03..3b9a6be51e8 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java @@ -33,7 +33,7 @@ public final class FluidStorageKeys { public static final FluidStorageKey PLASMA = new FluidStorageKey(gregtechId("plasma"), MaterialIconType.plasma, s -> "plasma." + s, m -> "gregtech.fluid.plasma", - FluidState.PLASMA); + FluidState.PLASMA, -1); private FluidStorageKeys() {} } diff --git a/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java b/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java index e4cbbab3310..ba4223d289f 100644 --- a/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/RecyclingRecipes.java @@ -140,7 +140,10 @@ private static void registerExtractorRecycling(ItemStack input, List ms.material.hasProperty(PropertyKey.FLUID)).findFirst() - .orElse(null); + MaterialStack fluidMs = materials.stream() + .filter(ms -> ms.material.hasProperty(PropertyKey.FLUID) && ms.material.getFluid() != null) + .findFirst().orElse(null); if (fluidMs == null) return; // Find the next MaterialStack, which will be the Item output. From 028562cbbd6b68b438884a0bf38eca7d5af89d22 Mon Sep 17 00:00:00 2001 From: Tictim Date: Mon, 18 Dec 2023 09:42:38 +0900 Subject: [PATCH 028/168] Ore Dictionary Filter Update (#2296) --- src/main/java/gregtech/GregTechMod.java | 15 +- .../java/gregtech/api/gui/GuiTextures.java | 4 + .../gregtech/api/util/oreglob/OreGlob.java | 127 ++++++++++++--- .../api/util/oreglob/OreGlobCompiler.java | 10 ++ .../filter/OreDictionaryItemFilter.java | 146 ++++++++++++++---- .../filter/oreglob/impl/OreGlobMessages.java | 13 ++ .../filter/oreglob/impl/OreGlobParser.java | 44 +++--- .../widget/orefilter/OreFilterTestSlot.java | 63 ++++---- src/main/java/gregtech/core/CoreModule.java | 4 + .../resources/assets/gregtech/lang/en_us.lang | 6 +- .../ore_filter/button_case_sensitive.png | Bin 0 -> 339 bytes .../widget/ore_filter/button_match_all.png | Bin 0 -> 386 bytes .../java/gregtech/api/util/OreGlobTest.java | 17 +- 13 files changed, 322 insertions(+), 127 deletions(-) create mode 100644 src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_case_sensitive.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_match_all.png diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 1942c3a0c9f..3d9cbeabd6c 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -3,9 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.modules.ModuleContainerRegistryEvent; -import gregtech.api.util.oreglob.OreGlob; import gregtech.client.utils.BloomEffectUtil; -import gregtech.common.covers.filter.oreglob.impl.OreGlobParser; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; @@ -15,7 +13,17 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.event.*; +import net.minecraftforge.fml.common.event.FMLConstructionEvent; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLInterModComms; +import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; +import net.minecraftforge.fml.common.event.FMLServerStartedEvent; +import net.minecraftforge.fml.common.event.FMLServerStartingEvent; +import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; +import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; @Mod(modid = GTValues.MODID, name = "GregTech", @@ -43,7 +51,6 @@ public GregTechMod() { public void onConstruction(FMLConstructionEvent event) { moduleManager = ModuleManager.getInstance(); GregTechAPI.moduleManager = moduleManager; - OreGlob.setCompiler(input -> new OreGlobParser(input).compile()); moduleManager.registerContainer(new GregTechModules()); MinecraftForge.EVENT_BUS.post(new ModuleContainerRegistryEvent()); moduleManager.setup(event.getASMHarvestedData(), Loader.instance().getConfigDir()); diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index 20936a052b2..e2a19ec6dcb 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -435,6 +435,10 @@ public class GuiTextures { .fullImage("textures/items/metaitems/cover.controller.png"); // Ore Filter + public static final TextureArea ORE_FILTER_BUTTON_CASE_SENSITIVE = TextureArea + .fullImage("textures/gui/widget/ore_filter/button_case_sensitive.png"); + public static final TextureArea ORE_FILTER_BUTTON_MATCH_ALL = TextureArea + .fullImage("textures/gui/widget/ore_filter/button_match_all.png"); public static final TextureArea ORE_FILTER_INFO = TextureArea.fullImage("textures/gui/widget/ore_filter/info.png"); public static final TextureArea ORE_FILTER_SUCCESS = TextureArea .fullImage("textures/gui/widget/ore_filter/success.png"); diff --git a/src/main/java/gregtech/api/util/oreglob/OreGlob.java b/src/main/java/gregtech/api/util/oreglob/OreGlob.java index 072e4959eeb..a560fcae1bf 100644 --- a/src/main/java/gregtech/api/util/oreglob/OreGlob.java +++ b/src/main/java/gregtech/api/util/oreglob/OreGlob.java @@ -7,21 +7,19 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.List; -import java.util.Set; -import java.util.function.Function; /** * Glob-like string matcher language designed for ore dictionary matching. *

- * An OreGlob instance provides two functions: the ability to match strings, - * and the ability to translate expression structure into user-friendly text - * explanations. The text can be either a plaintext, or a text formatted by standard + * An OreGlob instance provides two functions: the ability to match strings, and the ability to translate expression + * structure into user-friendly text explanations. The text can be either a plaintext, or a text formatted by standard * Minecraft text format. */ public abstract class OreGlob { - private static Function compiler; + private static OreGlobCompiler compiler; /** * Tries to compile the string expression into OreGlob instance. @@ -29,15 +27,31 @@ public abstract class OreGlob { * @param expression OreGlob expression * @return Compilation result * @throws IllegalStateException If compiler is not provided yet + * @deprecated use {@link #compile(String, boolean)} */ @NotNull + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static OreGlobCompileResult compile(@NotNull String expression) { + return compile(expression, true); + } + + /** + * Tries to compile the string expression into OreGlob instance. + * + * @param expression OreGlob expression + * @param ignoreCase Whether the resulting OreGlob instance should do case-insensitive matches + * @return Compilation result + * @throws IllegalStateException If compiler is not provided yet + */ + @NotNull + public static OreGlobCompileResult compile(@NotNull String expression, boolean ignoreCase) { if (compiler == null) throw new IllegalStateException("Compiler unavailable"); - return compiler.apply(expression); + return compiler.compile(expression, ignoreCase); } @ApiStatus.Internal - public static void setCompiler(@NotNull Function compiler) { + public static void setCompiler(@NotNull OreGlobCompiler compiler) { OreGlob.compiler = compiler; } @@ -60,30 +74,97 @@ public static void setCompiler(@NotNull Function c public abstract boolean matches(@NotNull String input); /** - * Tries to match each ore dictionary entries associated with given item. - * If any of them matches, {@code true} is returned. *

- * For items not associated with any ore dictionary entries, this method returns - * {@code true} if this instance matches empty string instead. + * Tries to match each ore dictionary entries associated with given item. If any of them matches, {@code true} is + * returned. + *

+ *

+ * For items not associated with any ore dictionary entries, this method returns {@code true} if this instance + * matches empty string instead. + *

* * @param stack Item input * @return Whether this instance matches the input + * @deprecated use {@link #matchesAll(ItemStack)} or {@link #matchesAny(ItemStack)} */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public final boolean matches(@NotNull ItemStack stack) { - Set oreDicts = OreDictUnifier.getOreDictionaryNames(stack); - if (oreDicts.isEmpty()) { - return matches(""); - } else { - for (String oreDict : oreDicts) { - if (matches(oreDict)) return true; - } - return false; - } + return matchesAny(stack); + } + + /** + *

+ * Tries to match each ore dictionary entries associated with given item. If any of them matches, {@code true} is + * returned. + *

+ *

+ * For items not associated with any ore dictionary entries, this method returns {@code true} if this instance + * matches empty string instead. + *

+ * + * @param stack Item input + * @return Whether this instance matches the input + */ + public final boolean matchesAny(@NotNull ItemStack stack) { + return matchesAny(OreDictUnifier.getOreDictionaryNames(stack), true); + } + + /** + *

+ * Tries to match each ore dictionary entries associated with given item. If all of them matches, {@code true} is + * returned. + *

+ *

+ * For items not associated with any ore dictionary entries, this method returns {@code true} if this instance + * matches empty string instead. + *

+ * + * @param stack Item input + * @return Whether this instance matches the input + */ + public final boolean matchesAll(@NotNull ItemStack stack) { + return matchesAll(OreDictUnifier.getOreDictionaryNames(stack), true); + } + + /** + *

+ * Tries to match each input. If any of them matches, {@code true} is returned. + *

+ * + * @param inputs Collection of input strings + * @param specialEmptyMatch If {@code true}, this method will match an empty string ({@code ""}) if the input + * collection is empty. If {@code true}, this method will return {@code false} in such + * scenario. + * @return Whether this instance matches the input + */ + public final boolean matchesAny(@NotNull Collection inputs, boolean specialEmptyMatch) { + if (specialEmptyMatch && inputs.isEmpty()) return matches(""); + for (String input : inputs) if (matches(input)) return true; + return false; + } + + /** + *

+ * Tries to match each input. If all of them matches, {@code true} is returned. Note that this method does not have + * special case for empty inputs. + *

+ * + * @param inputs Collection of input strings + * @param specialEmptyMatch If {@code true}, this method will match an empty string ({@code ""}) if the input + * collection is empty. If {@code true}, this method will return {@code true} in such + * scenario. + * @return Whether this instance matches the input + */ + public final boolean matchesAll(@NotNull Collection inputs, boolean specialEmptyMatch) { + if (specialEmptyMatch && inputs.isEmpty()) return matches(""); + for (String input : inputs) if (!matches(input)) return false; + return true; } /** - * Visualize this instance with standard Minecraft text formatting. Two spaces (' ') will - * be used as indentation. + * Visualize this instance with standard Minecraft text formatting. Two spaces ({@code ' '}) will be used as + * indentation. * * @return Formatted visualization * @see OreGlob#toFormattedString(String) diff --git a/src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java b/src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java new file mode 100644 index 00000000000..d66fb7785a0 --- /dev/null +++ b/src/main/java/gregtech/api/util/oreglob/OreGlobCompiler.java @@ -0,0 +1,10 @@ +package gregtech.api.util.oreglob; + +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface OreGlobCompiler { + + @NotNull + OreGlobCompileResult compile(@NotNull String expression, boolean ignoreCase); +} diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 95cc2f172e0..1db9a6087e3 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -2,12 +2,15 @@ import gregtech.api.gui.GuiTextures; import gregtech.api.gui.Widget; +import gregtech.api.gui.resources.TextureArea; import gregtech.api.gui.widgets.DrawableWidget; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.ItemVariantMap; import gregtech.api.unification.stack.MultiItemVariantMap; import gregtech.api.unification.stack.SingleItemVariantMap; +import gregtech.api.util.function.BooleanConsumer; import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.oreglob.OreGlobCompileResult; import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; @@ -18,55 +21,90 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.text.TextFormatting; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.Set; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; public class OreDictionaryItemFilter extends ItemFilter { + private final Map> matchCache = new Object2ObjectOpenHashMap<>(); + private final SingleItemVariantMap noOreDictMatch = new SingleItemVariantMap<>(); + protected String expression = ""; + private OreGlob glob = ImpossibleOreGlob.getInstance(); private boolean error; - private final Map> matchCache = new Object2ObjectOpenHashMap<>(); - private final SingleItemVariantMap noOreDictMatch = new SingleItemVariantMap<>(); + private boolean caseSensitive; + /** + * {@code false} requires any of the entry to be match in order for the match to be success, {@code true} requires + * all entries to match + */ + private boolean matchAll; + @NotNull public String getExpression() { return expression; } + @NotNull + public OreGlob getGlob() { + return this.glob; + } + + protected void recompile(@Nullable Consumer<@Nullable OreGlobCompileResult> callback) { + clearCache(); + String expr = this.expression; + if (!expr.isEmpty()) { + OreGlobCompileResult result = OreGlob.compile(expr, !this.caseSensitive); + this.glob = result.getInstance(); + this.error = result.hasError(); + if (callback != null) callback.accept(result); + } else { + this.glob = ImpossibleOreGlob.getInstance(); + this.error = true; + if (callback != null) callback.accept(null); + } + } + + protected void clearCache() { + this.matchCache.clear(); + this.noOreDictMatch.clear(); + } + @Override public void initUI(Consumer widgetGroup) { ItemOreFilterTestSlot[] testSlot = new ItemOreFilterTestSlot[5]; for (int i = 0; i < testSlot.length; i++) { - testSlot[i] = new ItemOreFilterTestSlot(20 + 22 * i, 0); - widgetGroup.accept(testSlot[i]); + ItemOreFilterTestSlot slot = new ItemOreFilterTestSlot(20 + 22 * i, 0); + slot.setGlob(getGlob()); + slot.setMatchAll(this.matchAll); + widgetGroup.accept(slot); + testSlot[i] = slot; } OreGlobCompileStatusWidget compilationStatus = new OreGlobCompileStatusWidget(10, 10); + + Consumer<@Nullable OreGlobCompileResult> compileCallback = result -> { + compilationStatus.setCompileResult(result); + for (ItemOreFilterTestSlot slot : testSlot) { + slot.setGlob(getGlob()); + } + }; + HighlightedTextField textField = new HighlightedTextField(14, 26, 152, 14, () -> this.expression, s -> { if (s.equals(this.expression)) return; this.expression = s; - if (!s.isEmpty()) { - OreGlobCompileResult result = OreGlob.compile(s); - this.glob = result.getInstance(); - this.error = result.hasError(); - compilationStatus.setCompileResult(result); - } else { - this.glob = ImpossibleOreGlob.getInstance(); - this.error = true; - compilationStatus.setCompileResult(null); - } - this.matchCache.clear(); - this.noOreDictMatch.clear(); markDirty(); - for (ItemOreFilterTestSlot slot : testSlot) { - slot.setGlob(this.error ? null : this.glob); - } + recompile(compileCallback); }); compilationStatus.setTextField(textField); @@ -91,7 +129,7 @@ public void initUI(Consumer widgetGroup) { case '*', '?' -> h.format(i, TextFormatting.GREEN); case '!' -> h.format(i, TextFormatting.RED); case '\\' -> h.format(i++, TextFormatting.YELLOW); - case '$' -> { + case '$' -> { // TODO: remove this switch case in 2.9 h.format(i, TextFormatting.DARK_GREEN); for (; i < t.length(); i++) { switch (t.charAt(i)) { @@ -114,6 +152,25 @@ public void initUI(Consumer widgetGroup) { h.format(i + 1, TextFormatting.RESET); } }).setMaxLength(64)); + widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(130, 38, 18, 18, + GuiTextures.ORE_FILTER_BUTTON_CASE_SENSITIVE, () -> this.caseSensitive, caseSensitive -> { + if (this.caseSensitive == caseSensitive) return; + this.caseSensitive = caseSensitive; + markDirty(); + recompile(compileCallback); + }).setTooltipHoverString( + i -> "cover.ore_dictionary_filter.button.case_sensitive." + (i == 0 ? "disabled" : "enabled"))); + widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(148, 38, 18, 18, + GuiTextures.ORE_FILTER_BUTTON_MATCH_ALL, () -> this.matchAll, matchAll -> { + if (this.matchAll == matchAll) return; + this.matchAll = matchAll; + markDirty(); + clearCache(); + for (ItemOreFilterTestSlot slot : testSlot) { + slot.setMatchAll(matchAll); + } + }).setTooltipHoverString( + i -> "cover.ore_dictionary_filter.button.match_all." + (i == 0 ? "disabled" : "enabled"))); } @Override @@ -122,7 +179,7 @@ public Object matchItemStack(ItemStack itemStack) { "wtf is this system?? i can put any non null object here and it i will work??? $arch" : null; } - public boolean matchesItemStack(ItemStack itemStack) { + public boolean matchesItemStack(@NotNull ItemStack itemStack) { if (this.error) return false; Item item = itemStack.getItem(); ItemVariantMap> oreDictEntry = OreDictUnifier.getOreDictionaryEntry(item); @@ -160,7 +217,7 @@ public boolean matchesItemStack(ItemStack itemStack) { } this.matchCache.put(item, cacheEntry); } - boolean matches = this.glob.matches(itemStack); + boolean matches = this.matchAll ? this.glob.matchesAll(itemStack) : this.glob.matchesAny(itemStack); cacheEntry.put(itemStack, matches); return matches; } @@ -181,20 +238,43 @@ public int getTotalOccupiedHeight() { } @Override - public void writeToNBT(NBTTagCompound tagCompound) { - tagCompound.setString("OreDictionaryFilter", expression); + public void writeToNBT(NBTTagCompound tag) { + tag.setString("OreDictionaryFilter", expression); + if (this.caseSensitive) tag.setBoolean("caseSensitive", true); + if (this.matchAll) tag.setBoolean("matchAll", true); } @Override - public void readFromNBT(NBTTagCompound tagCompound) { - this.expression = tagCompound.getString("OreDictionaryFilter"); - if (!this.expression.isEmpty()) { - OreGlobCompileResult result = OreGlob.compile(this.expression); - this.glob = result.getInstance(); - this.error = result.hasError(); - } else { - this.glob = ImpossibleOreGlob.getInstance(); - this.error = true; + public void readFromNBT(NBTTagCompound tag) { + this.expression = tag.getString("OreDictionaryFilter"); + this.caseSensitive = tag.getBoolean("caseSensitive"); + this.matchAll = tag.getBoolean("matchAll"); + recompile(null); + } + + public static class ForcedInitialSyncImageCycleButtonWidget extends ImageCycleButtonWidget { + + private final BooleanConsumer updater; + + public ForcedInitialSyncImageCycleButtonWidget(int xPosition, int yPosition, int width, int height, + TextureArea buttonTexture, BooleanSupplier supplier, + BooleanConsumer updater) { + super(xPosition, yPosition, width, height, buttonTexture, supplier, updater); + this.currentOption = 0; + this.updater = updater; + } + + @Override + public void readUpdateInfo(int id, PacketBuffer buffer) { + if (id == 1) { + int currentOptionCache = this.currentOption; + super.readUpdateInfo(id, buffer); + if (this.currentOption != currentOptionCache) { + this.updater.apply(currentOption >= 1); // call updater to apply necessary state changes + } + } else { + super.readUpdateInfo(id, buffer); + } } } } diff --git a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java index 6b3da3ca6fd..d0c2d44e7df 100644 --- a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java +++ b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobMessages.java @@ -2,6 +2,8 @@ import gregtech.api.util.LocalizationUtils; +import org.jetbrains.annotations.ApiStatus; + import java.util.Locale; interface OreGlobMessages { @@ -102,21 +104,32 @@ static String compileErrorUnexpectedTokenAfterEOF(String token) { return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "unexpected_token_after_eof", token); } + // compilation flags are expected to be removed in future release + + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorUnexpectedCompilationFlag() { // Compilation flags in the middle of expression return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "unexpected_compilation_flag"); } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorEmptyCompilationFlag() { // No compilation flags given return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "empty_compilation_flag"); } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorUnknownCompilationFlag(String flag) { // Unknown compilation flag '%s' return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "unknown_compilation_flag", flag); } + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") static String compileErrorRedundantCompilationFlag(String flag) { // Compilation flag '%s' written twice return LocalizationUtils.format(COMPILE_ERROR_PREFIX + "redundant_compilation_flag", flag); diff --git a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java index 0bc564d69db..b4cec035040 100644 --- a/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java +++ b/src/main/java/gregtech/common/covers/filter/oreglob/impl/OreGlobParser.java @@ -5,6 +5,7 @@ import gregtech.common.covers.filter.oreglob.node.OreGlobNode; import gregtech.common.covers.filter.oreglob.node.OreGlobNodes; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -14,7 +15,7 @@ /** * Top-down parser for oreGlob expression. - * + * *
  * oreGlob = [ FLAG ], [ or ], EOF
  *
@@ -47,8 +48,7 @@ public final class OreGlobParser {
 
     private boolean error;
 
-    private boolean caseSensitive;
-
+    private boolean ignoreCase;
     private int inputIndex;
 
     private TokenType tokenType;
@@ -56,8 +56,9 @@ public final class OreGlobParser {
     @Nullable
     private String tokenLiteralValue;
 
-    public OreGlobParser(String input) {
+    public OreGlobParser(String input, boolean ignoreCase) {
         this.input = input;
+        this.ignoreCase = ignoreCase;
     }
 
     // Get codepoint at current position and incr index
@@ -68,6 +69,7 @@ private int readNextChar() {
         return input.codePointAt(i);
     }
 
+    @SuppressWarnings("deprecation")
     private void advance() {
         boolean first = this.inputIndex == 0;
         while (true) {
@@ -84,7 +86,7 @@ private void advance() {
                 case '^' -> setCurrentToken(XOR, start, 1);
                 case '*' -> setCurrentToken(ANY, start, 1);
                 case '?' -> setCurrentToken(ANY_CHAR, start, 1);
-                case '$' -> {
+                case '$' -> { // TODO: remove this switch case in 2.9
                     if (!first) {
                         error(OreGlobMessages.compileErrorUnexpectedCompilationFlag(), start, 1);
                     }
@@ -145,8 +147,10 @@ private String gatherLiteralValue() {
         }
     }
 
+    @Deprecated
+    @SuppressWarnings("DeprecatedIsStillUsed")
+    @ApiStatus.ScheduledForRemoval(inVersion = "2.9")
     private void gatherFlags(boolean add) {
-        boolean flagsAdded = false;
         while (true) {
             int i = this.inputIndex;
             int c = readNextChar();
@@ -156,39 +160,27 @@ private void gatherFlags(boolean add) {
                     if (c == CHAR_EOF) {
                         error(OreGlobMessages.compileErrorEOFAfterEscape(), i, 1);
                     } else if (add) {
-                        addFlag(c, i);
-                        flagsAdded = true;
+                        addFlag(c);
                         continue;
                     }
                 }
                 case ' ', '\t', '\n', '\r', CHAR_EOF -> {}
                 default -> {
                     if (add) {
-                        addFlag(c, i);
-                        flagsAdded = true;
+                        addFlag(c);
                     }
                     continue;
                 }
             }
-            if (!flagsAdded && add) {
-                error(OreGlobMessages.compileErrorEmptyCompilationFlag(), i, 1);
-            }
+            warn("Compilation flags ('$') are scheduled to be removed in future releases.");
             return;
         }
     }
 
-    private void addFlag(int flag, int index) {
-        switch (flag) {
-            case 'c', 'C' -> {
-                if (this.caseSensitive) {
-                    warn(OreGlobMessages.compileErrorRedundantCompilationFlag("c"), index, 1);
-                } else {
-                    this.caseSensitive = true;
-                }
-            }
-            default -> warn(OreGlobMessages.compileErrorUnknownCompilationFlag(
-                    new StringBuilder().appendCodePoint(flag).toString()), index, 1);
-        }
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval(inVersion = "2.9")
+    private void addFlag(int flag) {
+        if (flag == 'c' || flag == 'C') this.ignoreCase = false;
     }
 
     private boolean advanceIf(TokenType type) {
@@ -296,7 +288,7 @@ private OreGlobNode primary() {
         return switch (tokenType) {
             case LITERAL -> {
                 if (tokenLiteralValue != null) {
-                    OreGlobNode result = OreGlobNodes.match(tokenLiteralValue, !this.caseSensitive);
+                    OreGlobNode result = OreGlobNodes.match(tokenLiteralValue, this.ignoreCase);
                     advance();
                     yield result;
                 } else { // likely caused by program error, not user issue
diff --git a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java
index 6bde8f6cb5b..fd81e80bcd7 100644
--- a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java
+++ b/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java
@@ -23,7 +23,6 @@
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -32,6 +31,9 @@
  */
 public abstract class OreFilterTestSlot extends WidgetGroup {
 
+    private final ImageWidget match;
+    private final ImageWidget noMatch;
+
     @Nullable
     private OreGlob glob;
     private boolean expectedResult = true;
@@ -48,8 +50,7 @@ public abstract class OreFilterTestSlot extends WidgetGroup {
 
     private boolean initialized = false;
 
-    private final ImageWidget match;
-    private final ImageWidget noMatch;
+    private boolean matchAll;
 
     public OreFilterTestSlot(int xPosition, int yPosition) {
         super(xPosition, yPosition, 18, 18);
@@ -86,30 +87,42 @@ public OreFilterTestSlot onMatchChange(@Nullable BooleanConsumer onMatchChange)
     }
 
     public void setGlob(@Nullable OreGlob glob) {
+        if (this.glob == glob) return;
         this.glob = glob;
         updatePreview();
     }
 
+    public void setMatchAll(boolean matchAll) {
+        if (this.matchAll == matchAll) return;
+        this.matchAll = matchAll;
+        updatePreview();
+    }
+
     protected void updatePreview() {
         if (!this.initialized) return;
         Set oreDicts = getTestCandidates();
         if (oreDicts != null) {
-            boolean success;
             OreGlob glob = this.glob;
             if (oreDicts.isEmpty()) {
                 // no oredict entries
-                this.testResult = Object2BooleanMaps.singleton("", success = glob != null && glob.matches(""));
+                this.testResult = Object2BooleanMaps.singleton("", glob != null && glob.matches(""));
                 this.matchType = MatchType.NO_ORE_DICT_MATCH;
             } else {
                 this.testResult = new Object2BooleanAVLTreeMap<>();
-                success = false;
                 for (String oreDict : oreDicts) {
                     boolean matches = glob != null && glob.matches(oreDict);
                     this.testResult.put(oreDict, matches);
-                    success |= matches;
                 }
                 this.matchType = MatchType.ORE_DICT_MATCH;
             }
+            boolean success = this.matchAll;
+            for (var e : testResult.object2BooleanEntrySet()) {
+                boolean result = e.getBooleanValue();
+                if (result == !this.matchAll) {
+                    success = !this.matchAll;
+                    break;
+                }
+            }
             updateAndNotifyMatchSuccess(this.expectedResult == success);
             this.match.setVisible(this.expectedResult == success);
             this.noMatch.setVisible(this.expectedResult != success);
@@ -131,9 +144,8 @@ private void updateAndNotifyMatchSuccess(boolean newValue) {
     }
 
     /**
-     * Get each test candidate for current state of test slot. An empty collection indicates that the
-     * match is for items without any ore dictionary entry. A {@code null} value indicates that the
-     * input state is invalid or empty.
+     * Get each test candidate for current state of test slot. An empty collection indicates that the match is for items
+     * without any ore dictionary entry. A {@code null} value indicates that the input state is invalid or empty.
      *
      * @return each test candidate for current state of test slot
      */
@@ -168,26 +180,17 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender
     @Override
     public void drawInForeground(int mouseX, int mouseY) {
         if (isActive() && isMouseOverElement(mouseX, mouseY)) {
-            List list;
-            switch (this.matchType) {
-                case NO_ORE_DICT_MATCH:
-                    list = Collections.singletonList(I18n.format(this.matchSuccess ?
-                            "cover.ore_dictionary_filter.test_slot.no_oredict.matches" :
-                            "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not"));
-                    break;
-                case ORE_DICT_MATCH:
-                    list = this.testResult.object2BooleanEntrySet().stream().map(
-                            e -> I18n.format(e.getBooleanValue() ?
-                                    "cover.ore_dictionary_filter.test_slot.matches" :
-                                    "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey()))
-                            .collect(Collectors.toList());
-                    break;
-                case INVALID:
-                default:
-                    list = Arrays.asList(LocalizationUtils.formatLines("cover.ore_dictionary_filter.test_slot.info"));
-                    break;
-            }
-            drawHoveringText(ItemStack.EMPTY, list, 300, mouseX, mouseY);
+            drawHoveringText(ItemStack.EMPTY, switch (this.matchType) {
+                case NO_ORE_DICT_MATCH -> Collections.singletonList(I18n.format(this.matchSuccess ?
+                        "cover.ore_dictionary_filter.test_slot.no_oredict.matches" :
+                        "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not"));
+                case ORE_DICT_MATCH -> this.testResult.object2BooleanEntrySet().stream().map(
+                        e -> I18n.format(e.getBooleanValue() ?
+                                "cover.ore_dictionary_filter.test_slot.matches" :
+                                "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey()))
+                        .collect(Collectors.toList());
+                default -> Arrays.asList(LocalizationUtils.formatLines("cover.ore_dictionary_filter.test_slot.info"));
+            }, 300, mouseX, mouseY);
         }
     }
 
diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java
index c063eec5c15..d103159380f 100644
--- a/src/main/java/gregtech/core/CoreModule.java
+++ b/src/main/java/gregtech/core/CoreModule.java
@@ -25,6 +25,7 @@
 import gregtech.api.util.CapesRegistry;
 import gregtech.api.util.VirtualTankRegistry;
 import gregtech.api.util.input.KeyBind;
+import gregtech.api.util.oreglob.OreGlob;
 import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler;
 import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData;
 import gregtech.api.worldgen.config.WorldGenRegistry;
@@ -40,6 +41,7 @@
 import gregtech.common.command.worldgen.CommandWorldgen;
 import gregtech.common.covers.CoverBehaviors;
 import gregtech.common.covers.filter.FilterTypeRegistry;
+import gregtech.common.covers.filter.oreglob.impl.OreGlobParser;
 import gregtech.common.items.MetaItems;
 import gregtech.common.items.ToolItems;
 import gregtech.common.metatileentities.MetaTileEntities;
@@ -111,6 +113,8 @@ public CoreModule() {
         // must be set here because of GroovyScript compat
         // trying to read this before the pre-init stage
         GregTechAPI.materialManager = MaterialRegistryManager.getInstance();
+
+        OreGlob.setCompiler((expr, ignoreCase) -> new OreGlobParser(expr, ignoreCase).compile());
     }
 
     @NotNull
diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang
index 531dfc20c6a..0a99c369d6a 100644
--- a/src/main/resources/assets/gregtech/lang/en_us.lang
+++ b/src/main/resources/assets/gregtech/lang/en_us.lang
@@ -1175,7 +1175,7 @@ cover.filter.blacklist.disabled=Whitelist
 cover.filter.blacklist.enabled=Blacklist
 
 cover.ore_dictionary_filter.title=Ore Dictionary Filter
-cover.ore_dictionary_filter.info=§bAccepts complex expressions/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r for grouping/n§6*§r for wildcard (i.e. 0 or more characters)/n§6?§r for any 1 character/n§6()§r for matching empty entry (including items with no ore dictionary)/n§6$c§r at the start of expression for case-sensitive match/n§bExample:/n§6dust*Gold | (plate* & !*Double*)/nWill match all gold dusts of all sizes or all plates, but not double plates
+cover.ore_dictionary_filter.info=§bAccepts complex expressions/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r for grouping/n§6*§r for wildcard (i.e. 0 or more characters)/n§6?§r for any 1 character/n§6()§r for matching empty entry (including items with no ore dictionary)/n§bExample:/n§6dust*Gold | (plate* & !*Double*)/nWill match all gold dusts of all sizes or all plates, but not double plates
 cover.ore_dictionary_filter.test_slot.info=Insert a item to test if it matches the filter expression
 cover.ore_dictionary_filter.test_slot.matches=§a* %s
 cover.ore_dictionary_filter.test_slot.matches_not=§c* %s
@@ -1186,6 +1186,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s error(s) and %s warning(s)
 cover.ore_dictionary_filter.status.warn=§7%s warning(s)
 cover.ore_dictionary_filter.status.no_issues=§aNo issues
 cover.ore_dictionary_filter.status.explain=Ore filter explanation:
+cover.ore_dictionary_filter.button.case_sensitive.disabled=Case insensitive match
+cover.ore_dictionary_filter.button.case_sensitive.enabled=Case sensitive match
+cover.ore_dictionary_filter.button.match_all.disabled=Match any one of ore dictionary entries
+cover.ore_dictionary_filter.button.match_all.enabled=Match all ore dictionary entries
 
 cover.ore_dictionary_filter.preview.next=... followed by 
 cover.ore_dictionary_filter.preview.match='%s'
diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_case_sensitive.png b/src/main/resources/assets/gregtech/textures/gui/widget/ore_filter/button_case_sensitive.png
new file mode 100644
index 0000000000000000000000000000000000000000..6615e156d4f5b3426199403f095230d8d89c9eb0
GIT binary patch
literal 339
zcmV-Z0j&OsP)Px$4M{{nR7i>KmB9_eAPhx6Rc@W5t27HRKo-c=Lm;FcvOos#0-Ysu;)8WBqE$I^{%>fVz?ebJz=;W
zG50H+bM20tbC~L?DZIciY#9hIQF<<}~dTko`mR%qwFZ@LRj=C?a!+SqEl
zBao@uVho4~Q=_X*V>^jpF$N>_c2WcdCnph1kMUa|08b}lHR3KKB2rs5?L#j9*GiCB
l{|>1qP#yg{Px$JV``BR7i>Kls!(vKoEt$l|q4X19~@{0}&43jwTmKK{JOKS)#}VIKUhrL7anz
zJ~xO`Pz;5=mjAsZLZZm4tljbR`@HrG?(STuq9|Czi%Vo?r4hib2u~sOhIUoplWIM)
zbLXVmnhWmkF_D=~J~_|x)=Zw~{Y1@;IkO?vMjtoA-Tkt)dH6g6@bImzneICL0__(10Wq5dlD}ncC>2%5(SB%<4qV8%2c2S9pIJ
zNR)!H-Y=1ru--3uTOI2(qi9i0L{%L%fipfx5$TzjS=;DbnHh_sC}#iq6oqR;0@sF|
zik&iZZOBsHa*Nk3qq&BR`U-(ege|ZcN|b`3s$?RinfrMS8PT>t=3XXhl-xAh0OF=f
gwyEAx)c(OreGlobCompileResult.class) {
 
             @Override

From d41a0366455bc6f7ac8ce195b4dcd2dde8a21c5b Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Sun, 17 Dec 2023 19:42:55 -0500
Subject: [PATCH 029/168] invalidate pipenet routepaths on chunk unload (#2303)

---
 .../metatileentity/NeighborCacheTileEntityBase.java  | 11 +++++++++++
 src/main/java/gregtech/api/pipenet/PipeNet.java      | 12 +++++++++++-
 .../api/pipenet/tile/TileEntityPipeBase.java         | 12 ++++++++++++
 .../common/pipelike/cable/net/EnergyNet.java         | 10 +++++++++-
 .../common/pipelike/cable/tile/TileEntityCable.java  |  8 +++++++-
 .../common/pipelike/itempipe/net/ItemPipeNet.java    | 11 ++++++++++-
 .../pipelike/itempipe/tile/TileEntityItemPipe.java   |  6 ++++++
 .../common/pipelike/laser/net/LaserPipeNet.java      |  5 +++++
 .../pipelike/laser/tile/TileEntityLaserPipe.java     |  6 ++++++
 .../common/pipelike/optical/net/OpticalPipeNet.java  |  5 +++++
 .../pipelike/optical/tile/TileEntityOpticalPipe.java |  6 ++++++
 11 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java b/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java
index 473b950d63c..97200ab8518 100644
--- a/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java
+++ b/src/main/java/gregtech/api/metatileentity/NeighborCacheTileEntityBase.java
@@ -7,6 +7,7 @@
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.World;
 
+import org.jetbrains.annotations.MustBeInvokedByOverriders;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -28,24 +29,34 @@ protected void invalidateNeighbors() {
         }
     }
 
+    @MustBeInvokedByOverriders
     @Override
     public void setWorld(@NotNull World worldIn) {
         super.setWorld(worldIn);
         invalidateNeighbors();
     }
 
+    @MustBeInvokedByOverriders
     @Override
     public void setPos(@NotNull BlockPos posIn) {
         super.setPos(posIn);
         invalidateNeighbors();
     }
 
+    @MustBeInvokedByOverriders
     @Override
     public void invalidate() {
         super.invalidate();
         invalidateNeighbors();
     }
 
+    @MustBeInvokedByOverriders
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        invalidateNeighbors();
+    }
+
     @Override
     public @Nullable TileEntity getNeighbor(@NotNull EnumFacing facing) {
         if (world == null || pos == null) return null;
diff --git a/src/main/java/gregtech/api/pipenet/PipeNet.java b/src/main/java/gregtech/api/pipenet/PipeNet.java
index 384d15134a1..536b2a23b81 100644
--- a/src/main/java/gregtech/api/pipenet/PipeNet.java
+++ b/src/main/java/gregtech/api/pipenet/PipeNet.java
@@ -15,8 +15,13 @@
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 
-import java.util.*;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 public abstract class PipeNet implements INBTSerializable {
 
@@ -63,6 +68,11 @@ public void onPipeConnectionsUpdate() {}
 
     public void onNeighbourUpdate(BlockPos fromPos) {}
 
+    /**
+     * Is called when any Pipe TE in the PipeNet is unloaded
+     */
+    public void onChunkUnload() {}
+
     public Map> getAllNodes() {
         return unmodifiableNodeByBlockPos;
     }
diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
index a2d593bb206..b1ec074d9d6 100644
--- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
+++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
@@ -26,6 +26,7 @@
 import net.minecraftforge.common.capabilities.Capability;
 import net.minecraftforge.common.util.Constants.NBT;
 
+import org.jetbrains.annotations.MustBeInvokedByOverriders;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -539,6 +540,17 @@ public boolean shouldRefresh(@NotNull World world, @NotNull BlockPos pos, IBlock
         return oldState.getBlock() != newSate.getBlock();
     }
 
+    @MustBeInvokedByOverriders
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        WorldPipeNet worldPipeNet = getPipeBlock().getWorldPipeNet(getWorld());
+        PipeNet net = worldPipeNet.getNetFromPos(pos);
+        if (net != null) {
+            net.onChunkUnload();
+        }
+    }
+
     public void doExplosion(float explosionPower) {
         getWorld().setBlockToAir(getPos());
         if (!getWorld().isRemote) {
diff --git a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java
index 8d6f7110cb1..a56fb565600 100644
--- a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java
+++ b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java
@@ -11,7 +11,10 @@
 
 import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
 
 public class EnergyNet extends PipeNet {
 
@@ -67,6 +70,11 @@ public void onPipeConnectionsUpdate() {
         NET_DATA.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        NET_DATA.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java b/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java
index d54d160e525..befdf615466 100644
--- a/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java
+++ b/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java
@@ -258,7 +258,7 @@ public  T getCapabilityInternal(Capability capability, @Nullable EnumFacin
         if (capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER) {
             if (world.isRemote)
                 return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(clientCapability);
-            if (handlers.size() == 0)
+            if (handlers.isEmpty())
                 initHandlers();
             checkNetwork();
             return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(handlers.getOrDefault(facing, defaultHandler));
@@ -293,6 +293,12 @@ private EnergyNet getEnergyNet() {
         return currentEnergyNet;
     }
 
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
+
     @Override
     public int getDefaultPaintingColor() {
         return 0x404040;
diff --git a/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java b/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java
index 25e6534b0f4..c836119c344 100644
--- a/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java
+++ b/src/main/java/gregtech/common/pipelike/itempipe/net/ItemPipeNet.java
@@ -9,7 +9,11 @@
 import net.minecraft.util.EnumFacing;
 import net.minecraft.util.math.BlockPos;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class ItemPipeNet extends PipeNet {
 
@@ -43,6 +47,11 @@ public void onPipeConnectionsUpdate() {
         NET_DATA.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        NET_DATA.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java b/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java
index 5880f375964..80b5e233b92 100644
--- a/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java
+++ b/src/main/java/gregtech/common/pipelike/itempipe/tile/TileEntityItemPipe.java
@@ -153,4 +153,10 @@ public int getTransferredItems() {
         updateTransferredState();
         return this.transferredItems;
     }
+
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
 }
diff --git a/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java b/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java
index 02781ae8ce8..67aef2810ac 100644
--- a/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java
+++ b/src/main/java/gregtech/common/pipelike/laser/net/LaserPipeNet.java
@@ -46,6 +46,11 @@ public void onPipeConnectionsUpdate() {
         netData.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        netData.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java b/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java
index 6a11c0503a4..759fa494152 100644
--- a/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java
+++ b/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java
@@ -224,6 +224,12 @@ public void readFromNBT(@NotNull NBTTagCompound compound) {
         }
     }
 
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
+
     private static class DefaultLaserContainer implements ILaserContainer {
 
         @Override
diff --git a/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java b/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java
index 18f2edd36ca..fceabc6aae6 100644
--- a/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java
+++ b/src/main/java/gregtech/common/pipelike/optical/net/OpticalPipeNet.java
@@ -47,6 +47,11 @@ public void onPipeConnectionsUpdate() {
         NET_DATA.clear();
     }
 
+    @Override
+    public void onChunkUnload() {
+        NET_DATA.clear();
+    }
+
     @Override
     protected void transferNodeData(Map> transferredNodes,
                                     PipeNet parentNet) {
diff --git a/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java b/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java
index adf7f995ae1..43efe04cb56 100644
--- a/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java
+++ b/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java
@@ -194,6 +194,12 @@ public void receiveCustomData(int discriminator, PacketBuffer buf) {
         }
     }
 
+    @Override
+    public void onChunkUnload() {
+        super.onChunkUnload();
+        this.handlers.clear();
+    }
+
     private static class DefaultDataHandler implements IDataAccessHatch {
 
         @Override

From af3454beea06d8ebda843795976b3b3de543de2a Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 17 Dec 2023 18:43:12 -0600
Subject: [PATCH 030/168] Allow electrolyzing more hydrocarbons (#2258)

---
 .../materials/OrganicChemistryMaterials.java  |   6 +-
 .../recipe/chemistry/SeparationRecipes.java   | 124 ++++++++++++------
 2 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java
index f47c7cc0a42..de2bdf4a703 100644
--- a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java
+++ b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java
@@ -194,7 +194,6 @@ public static void register() {
         Chloromethane = new Material.Builder(1024, gregtechId("chloromethane"))
                 .gas()
                 .color(0xC82CA0)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 1, Hydrogen, 3, Chlorine, 1)
                 .build();
 
@@ -221,12 +220,14 @@ public static void register() {
         Propene = new Material.Builder(1028, gregtechId("propene"))
                 .gas()
                 .color(0xFFDD55)
+                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 3, Hydrogen, 6)
                 .build();
 
         Ethane = new Material.Builder(1029, gregtechId("ethane"))
                 .gas()
                 .color(0xC8C8FF)
+                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 2, Hydrogen, 6)
                 .build();
 
@@ -268,7 +269,6 @@ public static void register() {
         Ethenone = new Material.Builder(1035, gregtechId("ethenone"))
                 .fluid()
                 .color(0x141446)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 2, Hydrogen, 2, Oxygen, 1)
                 .build();
 
@@ -331,7 +331,6 @@ public static void register() {
         AceticAcid = new Material.Builder(1044, gregtechId("acetic_acid"))
                 .liquid(new FluidBuilder().attribute(FluidAttributes.ACID))
                 .color(0xC8B4A0)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 2, Hydrogen, 4, Oxygen, 2)
                 .build();
 
@@ -373,7 +372,6 @@ public static void register() {
         Acetone = new Material.Builder(1050, gregtechId("acetone"))
                 .fluid()
                 .color(0xAFAFAF)
-                .flags(DISABLE_DECOMPOSITION)
                 .components(Carbon, 3, Hydrogen, 6, Oxygen, 1)
                 .build();
 
diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java
index 3d51fc11124..fc433308a0d 100644
--- a/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java
+++ b/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java
@@ -369,44 +369,6 @@ public static void init() {
                 .output(dust, Carbon, 4)
                 .duration(100).EUt(60).buildAndRegister();
 
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(AceticAcid.getFluid(2000))
-                .fluidOutputs(Ethane.getFluid(1000))
-                .fluidOutputs(CarbonDioxide.getFluid(2000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(512).EUt(60).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Chloromethane.getFluid(2000))
-                .fluidOutputs(Ethane.getFluid(1000))
-                .fluidOutputs(Chlorine.getFluid(2000))
-                .duration(400).EUt(60).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Acetone.getFluid(2000))
-                .output(dust, Carbon, 3)
-                .fluidOutputs(Propane.getFluid(1000))
-                .fluidOutputs(Water.getFluid(2000))
-                .duration(480).EUt(60).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Butane.getFluid(1000))
-                .fluidOutputs(Butene.getFluid(1000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(240).EUt(VA[MV]).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Butene.getFluid(1000))
-                .fluidOutputs(Butadiene.getFluid(1000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(240).EUt(VA[MV]).buildAndRegister();
-
-        ELECTROLYZER_RECIPES.recipeBuilder()
-                .fluidInputs(Propane.getFluid(1000))
-                .fluidOutputs(Propene.getFluid(1000))
-                .fluidOutputs(Hydrogen.getFluid(2000))
-                .duration(640).EUt(VA[MV]).buildAndRegister();
-
         ELECTROLYZER_RECIPES.recipeBuilder()
                 .input(dust, Diamond)
                 .output(dust, Carbon, 64)
@@ -470,6 +432,92 @@ public static void init() {
                 .fluidOutputs(Chlorine.getFluid(1000))
                 .duration(288).EUt(60).buildAndRegister();
 
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Propane.getFluid(1000))
+                .output(dust, Carbon, 3)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(176).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Butene.getFluid(1000))
+                .output(dust, Carbon, 4)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(192).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Butane.getFluid(1000))
+                .output(dust, Carbon, 4)
+                .fluidOutputs(Hydrogen.getFluid(10000))
+                .duration(224).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Styrene.getFluid(1000))
+                .output(dust, Carbon, 8)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(384).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Butadiene.getFluid(1000))
+                .output(dust, Carbon, 4)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(240).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Phenol.getFluid(1000))
+                .output(dust, Carbon, 6)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .fluidOutputs(Oxygen.getFluid(1000))
+                .duration(312).EUt(90).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Ethylene.getFluid(1000))
+                .output(dust, Carbon, 2)
+                .fluidOutputs(Hydrogen.getFluid(4000))
+                .duration(96).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Benzene.getFluid(1000))
+                .output(dust, Carbon, 6)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(288).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Ethanol.getFluid(1000))
+                .output(dust, Carbon, 2)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .fluidOutputs(Oxygen.getFluid(1000))
+                .duration(144).EUt(90).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Toluene.getFluid(1000))
+                .output(dust, Carbon, 7)
+                .fluidOutputs(Hydrogen.getFluid(8000))
+                .duration(360).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Dimethylbenzene.getFluid(1000))
+                .output(dust, Carbon, 8)
+                .fluidOutputs(Hydrogen.getFluid(10000))
+                .duration(432).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Octane.getFluid(1000))
+                .output(dust, Carbon, 8)
+                .fluidOutputs(Hydrogen.getFluid(18000))
+                .duration(624).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Propene.getFluid(1000))
+                .output(dust, Carbon, 3)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(144).EUt(60).buildAndRegister();
+
+        ELECTROLYZER_RECIPES.recipeBuilder()
+                .fluidInputs(Ethane.getFluid(1000))
+                .output(dust, Carbon, 2)
+                .fluidOutputs(Hydrogen.getFluid(6000))
+                .duration(128).EUt(60).buildAndRegister();
+
         // Thermal Centrifuge
         THERMAL_CENTRIFUGE_RECIPES.recipeBuilder()
                 .inputs(new ItemStack(Blocks.COBBLESTONE, 1, GTValues.W))

From 2bc744bb8cea61d88c21a239871180d111ed1869 Mon Sep 17 00:00:00 2001
From: serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 17 Dec 2023 18:44:43 -0600
Subject: [PATCH 031/168] 2.8.4

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 8ef839c11f9..ac0b7e7ae41 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,7 +7,7 @@ modGroup = gregtech
 
 # Version of your mod.
 # This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
-modVersion = 2.8.3-beta
+modVersion = 2.8.4-beta
 
 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version)
 includeMCVersionJar = true

From b5ddb56512ef21d38a1c559241f7c7bedeac53c3 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Sun, 17 Dec 2023 21:46:25 -0500
Subject: [PATCH 032/168] only access worldpipenet on server (#2310)

---
 .../gregtech/api/pipenet/WorldPipeNet.java    | 21 +++++++++++++++----
 .../api/pipenet/tile/TileEntityPipeBase.java  | 10 +++++----
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/main/java/gregtech/api/pipenet/WorldPipeNet.java b/src/main/java/gregtech/api/pipenet/WorldPipeNet.java
index 23860461888..03211cc377c 100644
--- a/src/main/java/gregtech/api/pipenet/WorldPipeNet.java
+++ b/src/main/java/gregtech/api/pipenet/WorldPipeNet.java
@@ -1,5 +1,7 @@
 package gregtech.api.pipenet;
 
+import gregtech.api.util.GTLog;
+
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.nbt.NBTTagList;
 import net.minecraft.util.EnumFacing;
@@ -12,7 +14,11 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.lang.ref.WeakReference;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public abstract class WorldPipeNet> extends WorldSavedData {
 
@@ -35,9 +41,16 @@ protected void setWorldAndInit(World world) {
         }
     }
 
-    public static String getDataID(final String baseID, final World world) {
-        if (world == null || world.isRemote)
-            throw new RuntimeException("WorldPipeNet should only be created on the server!");
+    public static @NotNull String getDataID(@NotNull final String baseID, @NotNull final World world) {
+        // noinspection ConstantValue
+        if (world == null || world.isRemote) {
+            GTLog.logger.error("WorldPipeNet should only be created on the server!", new Throwable());
+            // noinspection ConstantValue
+            if (world == null) {
+                return baseID;
+            }
+        }
+
         int dimension = world.provider.getDimension();
         return dimension == 0 ? baseID : baseID + '.' + dimension;
     }
diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
index b1ec074d9d6..84897a022e8 100644
--- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
+++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java
@@ -544,10 +544,12 @@ public boolean shouldRefresh(@NotNull World world, @NotNull BlockPos pos, IBlock
     @Override
     public void onChunkUnload() {
         super.onChunkUnload();
-        WorldPipeNet worldPipeNet = getPipeBlock().getWorldPipeNet(getWorld());
-        PipeNet net = worldPipeNet.getNetFromPos(pos);
-        if (net != null) {
-            net.onChunkUnload();
+        if (!world.isRemote) {
+            WorldPipeNet worldPipeNet = getPipeBlock().getWorldPipeNet(getWorld());
+            PipeNet net = worldPipeNet.getNetFromPos(pos);
+            if (net != null) {
+                net.onChunkUnload();
+            }
         }
     }
 

From 58c261364ed98f22352c8882978ad8e3acb50c6b Mon Sep 17 00:00:00 2001
From: serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 17 Dec 2023 20:46:51 -0600
Subject: [PATCH 033/168] 2.8.5

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index ac0b7e7ae41..102a8c549da 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,7 +7,7 @@ modGroup = gregtech
 
 # Version of your mod.
 # This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
-modVersion = 2.8.4-beta
+modVersion = 2.8.5-beta
 
 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version)
 includeMCVersionJar = true

From b08b88ca40f401daa24116b61d97de427be5e7b7 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Thu, 28 Dec 2023 19:49:43 -0500
Subject: [PATCH 034/168] update GHA workflows (#2270)

---
 .github/actions/build_setup/action.yml        | 30 +++++++
 .github/workflows/format_java.yml             | 29 +++++++
 .github/workflows/manage_pr_labels.yml        | 39 +++++++++
 .github/workflows/pr_artifact.yml             | 77 ----------------
 .github/workflows/pr_labels.yml               | 35 --------
 .github/workflows/pr_testing.yml              | 60 -------------
 .github/workflows/publish.yml                 | 87 -------------------
 .github/workflows/publish_project.yml         | 58 +++++++++++++
 .github/workflows/test_java.yml               | 31 +++++++
 .github/workflows/update_buildscript.yml      | 45 ++++------
 .github/workflows/update_gradle_cache.yml     | 39 ++++-----
 .github/workflows/validate_gradle_wrapper.yml |  7 +-
 12 files changed, 222 insertions(+), 315 deletions(-)
 create mode 100644 .github/actions/build_setup/action.yml
 create mode 100644 .github/workflows/format_java.yml
 create mode 100644 .github/workflows/manage_pr_labels.yml
 delete mode 100644 .github/workflows/pr_artifact.yml
 delete mode 100644 .github/workflows/pr_labels.yml
 delete mode 100644 .github/workflows/pr_testing.yml
 delete mode 100644 .github/workflows/publish.yml
 create mode 100644 .github/workflows/publish_project.yml
 create mode 100644 .github/workflows/test_java.yml

diff --git a/.github/actions/build_setup/action.yml b/.github/actions/build_setup/action.yml
new file mode 100644
index 00000000000..7409143dc18
--- /dev/null
+++ b/.github/actions/build_setup/action.yml
@@ -0,0 +1,30 @@
+name: Build Setup
+description: Setup for standard Java builds
+
+inputs:
+  update-cache:
+    description: If cache should be updated
+    required: false
+    default: false
+
+runs:
+  using: 'composite'
+
+  steps:
+  - name: Set up JDK 17
+    uses: actions/setup-java@v4
+    with:
+      distribution: zulu
+      java-version: 17
+
+  - name: Setup Gradle
+    uses: gradle/gradle-build-action@v2
+    with:
+      cache-write-only: ${{ inputs.update-cache }}
+      generate-job-summary: false
+      gradle-home-cache-includes: |
+        caches
+        caches/retro_futura_gradle
+        notifications
+        jdks
+        wrapper
diff --git a/.github/workflows/format_java.yml b/.github/workflows/format_java.yml
new file mode 100644
index 00000000000..e4537200c13
--- /dev/null
+++ b/.github/workflows/format_java.yml
@@ -0,0 +1,29 @@
+# Runs formatting requirements
+name: Java Formatting
+
+on:
+  push:
+    branches:
+      - master
+    paths: ['src/main/java/**', 'src/test/**']
+  pull_request:
+    paths: ['src/main/java/**', 'src/test/**']
+
+concurrency:
+  group: checks-${{ github.head_ref || github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  formatting:
+    name: Formatting
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
+
+      - name: Run Spotless Formatting Check with Gradle
+        run: ./gradlew spotlessCheck --warning-mode all --build-cache
diff --git a/.github/workflows/manage_pr_labels.yml b/.github/workflows/manage_pr_labels.yml
new file mode 100644
index 00000000000..7dcddd620b4
--- /dev/null
+++ b/.github/workflows/manage_pr_labels.yml
@@ -0,0 +1,39 @@
+# Manages labels on PRs before allowing merging
+name: Pull Request Labels
+
+on:
+  pull_request:
+    types:
+      - opened
+      - labeled
+      - unlabeled
+      - synchronize
+
+# if a second commit is pushed quickly after the first, cancel the first one's build
+concurrency:
+  group: pr-labels-${{ github.head_ref }}
+  cancel-in-progress: true
+
+jobs:
+  Labels:
+    runs-on: ubuntu-latest
+
+    permissions:
+      pull-requests: read # needed to utilize required-labels
+
+    steps:
+      - name: Check for Merge-Blocking Labels # blocks merge if present
+        uses: mheap/github-action-required-labels@v5
+        with:
+          mode: exactly
+          count: 0
+          labels: 'status: do not merge'
+          exit_type: failure
+
+      - name: Check for Required Labels # require at least one of these labels
+        uses: mheap/github-action-required-labels@v5
+        with:
+          mode: minimum
+          count: 1
+          labels: 'type: feature, type: bug, type: refactor, type: translation, ignore changelog'
+          exit_type: failure
diff --git a/.github/workflows/pr_artifact.yml b/.github/workflows/pr_artifact.yml
deleted file mode 100644
index 54187e2e326..00000000000
--- a/.github/workflows/pr_artifact.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-# Creates a built artifact jar for apropriately labeled Pull Requests
-name: PR Artifact
-
-on:
-  pull_request:
-    types: 
-      - labeled
-      - synchronize
-
-# if a second commit is pushed quickly after the first, cancel the first one's build
-concurrency:
-  group: build-artifact-${{github.head_ref}}
-  cancel-in-progress: true
-
-env:
-  ARTIFACT_NAME: 'gregtech-dev'
-  NOTIFICATION_BODY: |
-    This Pull Request has automatic artifact deployment enabled. Download the latest build [here](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}), and extract the contents.
-
-jobs:
-  Build_Artifact:
-    if: contains(github.event.pull_request.labels.*.name, format('deployment{0} artifact', ':'))
-    runs-on: ubuntu-latest
-
-    permissions: 
-      pull-requests: write # needed to make a comment
-      contents: read # needed to checkout the repo if defining other permissions
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-
-      - name: Build Project
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'build --build-cache --no-daemon ' # disable daemon since only one gradle operation will happen
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-
-      - name: Determine Artifact Name
-        id: artifact_name
-        run: |
-          FILE=(build/libs/*)
-          echo "artifact_name=${FILE[0]}" >> $GITHUB_OUTPUT
-
-      - name: Publish Artifact
-        uses: actions/upload-artifact@v3
-        with:
-          name: "${{env.ARTIFACT_NAME}}-${{github.head_ref}}-${{github.sha}}"
-          path: "${{steps.artifact_name.outputs.artifact_name}}"
-          if-no-files-found: error
-
-      - name: Find Existing Comment
-        uses: peter-evans/find-comment@v2
-        id: find-existing
-        with:
-          issue-number: ${{github.event.pull_request.number}}
-          comment-author: 'github-actions[bot]'
-          body-includes: 'Download the latest build [here]'
-
-      - name: Create or Update Artifact Publish Notification
-        uses: peter-evans/create-or-update-comment@v2
-        with:
-          issue-number: ${{github.event.pull_request.number}}
-          comment-id: ${{steps.find-existing.outputs.comment-id}}
-          edit-mode: replace
-          body: ${{env.NOTIFICATION_BODY}}
diff --git a/.github/workflows/pr_labels.yml b/.github/workflows/pr_labels.yml
deleted file mode 100644
index a47b267ec3c..00000000000
--- a/.github/workflows/pr_labels.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-# Manages labels on PRs before allowing merging
-name: PR labels
-
-on:
-  pull_request:
-    types: [opened, labeled, unlabeled, synchronize]
-
-# if a second commit is pushed quickly after the first, cancel the first one's build
-concurrency:
-  group: pr-labels-${{github.head_ref}}
-  cancel-in-progress: true
-
-jobs:
-  Labels:
-    runs-on: ubuntu-latest
-
-    permissions: 
-      pull-requests: read # needed to utilize required-labels
-
-    steps:
-      - name: Merge-Blocking Labels # blocks merge if present
-        uses: mheap/github-action-required-labels@v3
-        with:
-          mode: exactly
-          count: 0
-          labels: "status: do not merge"
-          exit_type: failure
-      
-      - name: Required Changelog Labels # require at least one of these labels
-        uses: mheap/github-action-required-labels@v3
-        with:
-          mode: minimum
-          count: 1
-          labels: "type: feature, type: bug, type: refactor, type: translation, ignore changelog"
-          exit_type: failure
diff --git a/.github/workflows/pr_testing.yml b/.github/workflows/pr_testing.yml
deleted file mode 100644
index 7761d2a8555..00000000000
--- a/.github/workflows/pr_testing.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# Runs tests and other checks on Pull Requests
-name: PR Testing
-
-on:
-  pull_request:
-    branches:
-      - master
-
-# if a second commit is pushed quickly after the first, cancel the first one's build
-concurrency:
-  group: pr-testing-${{github.head_ref}}
-  cancel-in-progress: true
-
-jobs:
-  Test:
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-
-      - name: Run Tests
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-
-  Formatting:
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-
-      - name: Run Spotless
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'spotlessCheck --build-cache'
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index df5366133a1..00000000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-# Publishes built jars to distribution platforms
-name: Publish
-
-on:
-  push:
-    tags:
-      - 'v[0-9]+.[0-9]+.[0-9]+' # any semver tag, e.g. v1.2.3
-
-env:
-  # link to the changelog with a format code for the version
-  CHANGELOG_LOCATION: "Changelog is available [here](https://github.com/${{github.repository}}/releases/tag/${{github.ref_name}})"
-  # type of release
-  RELEASE_TYPE: "beta"
-
-jobs:
-  Publish:
-    runs-on: ubuntu-latest
-
-    permissions: 
-      contents: write # needed to create GitHub releases
-
-    steps:
-      - name: Checkout Repository
-        uses: actions/checkout@v3
-      
-      - name: Check for Duplicate Tags
-        run: |
-          if git rev-parse -q --verify "refs/tags/${{ github.ref }}" >/dev/null; then
-            echo "Tag already exists. A version bump is required."
-            exit 1
-          fi
-
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
-      
-      - name: Build Project
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-      
-      - name: Publish to GitHub
-        uses: softprops/action-gh-release@v1
-        with:
-          files: "build/libs/*.jar"
-          generate_release_notes: true
-          fail_on_unmatched_files: true
-
-      - name: Publish to Curseforge
-        uses: gradle/gradle-build-action@v2
-        env:
-          CURSEFORGE_API_KEY: "${{secrets.CURSEFORGE_API_KEY}}"
-          CURSEFORGE_PROJECT_ID: "${{secrets.CURSEFORGE_PROJECT_ID}}"
-          CHANGELOG_LOCATION: "${{env.CHANGELOG_LOCATION}}"
-          RELEASE_TYPE: "${{env.RELEASE_TYPE}}"
-        with:
-          arguments: 'curseforge --daemon'
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-
-      - name: Publish to Modrinth
-        uses: gradle/gradle-build-action@v2
-        env:
-          MODRINTH_API_KEY: "${{secrets.MODRINTH_API_KEY}}"
-          MODRINTH_PROJECT_ID: "${{secrets.MODRINTH_PROJECT_ID}}"
-          CHANGELOG_LOCATION: "${{env.CHANGELOG_LOCATION}}"
-          RELEASE_TYPE: "${{env.RELEASE_TYPE}}"
-        with:
-          arguments: 'modrinth --daemon'
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml
new file mode 100644
index 00000000000..2172ac6806e
--- /dev/null
+++ b/.github/workflows/publish_project.yml
@@ -0,0 +1,58 @@
+# Publishes the project to GitHub Releases, CurseForge, and Modrinth
+name: Publish Project
+
+on:
+  push:
+    tags:
+      - 'v[0-9]+.[0-9]+.[0-9]+' # any SemVer tag, e.g. v1.2.3
+
+env:
+  # link to the changelog with a format code for the version
+  CHANGELOG_LOCATION: "Changelog is available [here](https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }})"
+  # type of release
+  RELEASE_TYPE: 'beta'
+
+concurrency:
+  group: publish-${{ github.head_ref || github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  publish:
+    name: Publish
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: write # needed to create GitHub releases
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
+
+      - name: Build Project
+        run: ./gradlew build --warning-mode all --build-cache
+
+      - name: Publish to GitHub
+        uses: softprops/action-gh-release@v1
+        with:
+          files: "build/libs/*.jar"
+          generate_release_notes: true
+          fail_on_unmatched_files: true
+
+      - name: Publish to Curseforge
+        env:
+          CURSEFORGE_API_KEY: "${{ secrets.CURSEFORGE_API_KEY }}"
+          CURSEFORGE_PROJECT_ID: "${{ secrets.CURSEFORGE_PROJECT_ID }}"
+          CHANGELOG_LOCATION: "${{ env.CHANGELOG_LOCATION }}"
+          RELEASE_TYPE: "${{ env.RELEASE_TYPE }}"
+        run: ./gradlew curseforge --warning-mode all --build-cache
+
+      - name: Publish to Modrinth
+        env:
+          MODRINTH_API_KEY: "${{ secrets.MODRINTH_API_KEY }}"
+          MODRINTH_PROJECT_ID: "${{ secrets.MODRINTH_PROJECT_ID }}"
+          CHANGELOG_LOCATION: "${{ env.CHANGELOG_LOCATION }}"
+          RELEASE_TYPE: "${{ env.RELEASE_TYPE }}"
+        run: ./gradlew modrinth --warning-mode all --build-cache
diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml
new file mode 100644
index 00000000000..4840c9fa34d
--- /dev/null
+++ b/.github/workflows/test_java.yml
@@ -0,0 +1,31 @@
+# Runs tests
+name: Java Tests
+
+on:
+  push:
+    branches:
+      - master
+    paths: ['src/main/java/**', 'src/test/**', 'src/api/java/**', 'gradle/**', '**.gradle', 'gradle.properties',
+            'gradlew**', 'src/main/resources/*_at.cfg']
+  pull_request:
+    paths: ['src/main/java/**', 'src/test/**', 'src/api/java/**', 'gradle/**', '**.gradle', 'gradle.properties',
+            'gradlew**', 'src/main/resources/*_at.cfg']
+
+concurrency:
+  group: checks-${{ github.head_ref || github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Tests
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
+
+      - name: Run Tests with Gradle
+        run: ./gradlew test --warning-mode all --build-cache
diff --git a/.github/workflows/update_buildscript.yml b/.github/workflows/update_buildscript.yml
index f8107f648d5..45fa46819d2 100644
--- a/.github/workflows/update_buildscript.yml
+++ b/.github/workflows/update_buildscript.yml
@@ -1,41 +1,33 @@
 # Checks daily to see if the buildscript is in need of an update
-name: Buildscript Updating
+name: Update Buildscript
 
 on:
   workflow_dispatch:
   schedule:
-    - cron: "0 0 * * *" # "min hr day month year", so run once per day
+    - cron: '0 0 * * *' # "min hr day month year", so run once per day
 
 jobs:
   buildscript-update:
     runs-on: ubuntu-latest
+
     # Avoid running this workflow on forks
     if: github.repository == 'GregTechCEu/GregTech'
+
     permissions:
       contents: write
       pull-requests: write
+
     steps:
-      - name: Checkout
-        uses: actions/checkout@v3
+      - name: Checkout Repository
+        uses: actions/checkout@v4
 
-      - name: Setup Java
-        uses: actions/setup-java@v3
-        with:
-          distribution: 'zulu'
-          java-version: '17'
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
 
-      - name: Run script updater
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'updateBuildScript'
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
+      - name: Run Buildscript Updater
+        run: ./gradlew updateBuildScript --warning-mode all --build-cache
 
-      - name: Get new script version
+      - name: Get New Buildscript Version
         id: version-check
         run: |
           new_version=$(head -1 build.gradle | sed -r 's|//version: (.*)|\1|g')
@@ -43,7 +35,7 @@ jobs:
 
       - name: Create Pull Request
         id: create-pull-request
-        uses: peter-evans/create-pull-request@v4
+        uses: peter-evans/create-pull-request@v5
         env:
           GITHUB_TOKEN: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }}
         with:
@@ -56,11 +48,8 @@ jobs:
           body: This pull request is created by the buildscript-update workflow
           labels: ignore changelog
 
-      - name: Enable pull request auto-merge
-        id: pull-request-auto-merge
+      - name: Enable Pull-Request Auto-Merge
         if: steps.create-pull-request.outputs.pull-request-operation == 'created'
-        uses: peter-evans/enable-pull-request-automerge@v3
-        with:
-          token: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }}
-          pull-request-number: ${{ steps.create-pull-request.outputs.pull-request-number }}
-          merge-method: squash
+        run: gh pr merge --squash --auto "${{ steps.create-pull-request.outputs.pull-request-number }}"
+        env:
+          GH_TOKEN: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }}
diff --git a/.github/workflows/update_gradle_cache.yml b/.github/workflows/update_gradle_cache.yml
index 9853000d7ac..ba93b16779a 100644
--- a/.github/workflows/update_gradle_cache.yml
+++ b/.github/workflows/update_gradle_cache.yml
@@ -1,39 +1,30 @@
-# Updates the Gradle Cache when relevant files change
+# Updates the Gradle Cache when necessary
 name: Update Gradle Cache
 
 on:
-  workflow_dispatch:
   push:
     branches:
       - master
-    paths:
-      - "gradle**" # covers gradle folder, gradle.properties, gradlew
-      - "build.gradle*"
-      - "settings.gradle*"
-      - "src/main/resources/*_at.cfg" # access transformers
+    paths: ['gradle/**', '**.gradle', 'gradle.properties', 'gradlew**', 'src/main/resources/*_at.cfg']
+  workflow_dispatch:
+
+concurrency:
+  group: gradle-cache-${{ github.ref }}
+  cancel-in-progress: true
 
 jobs:
-  Update_Cache:
+  update-cache:
+    name: Update Grade Cache
     runs-on: ubuntu-latest
 
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
-      - name: Setup Java
-        uses: actions/setup-java@v3
+      - name: Setup Build
+        uses: ./.github/actions/build_setup
         with:
-          distribution: 'zulu'
-          java-version: '17'
+          update-cache: true
 
-      - name: Update Cache
-        uses: gradle/gradle-build-action@v2
-        with:
-          arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen
-          generate-job-summary: false
-          gradle-home-cache-includes: |
-            caches
-            jdks
-            notifications
-            wrapper
-          cache-write-only: true
+      - name: Build Project with Gradle
+        run: ./gradlew assemble --warning-mode all --build-cache
diff --git a/.github/workflows/validate_gradle_wrapper.yml b/.github/workflows/validate_gradle_wrapper.yml
index 6f7a9d4cbe9..591e487d7d5 100644
--- a/.github/workflows/validate_gradle_wrapper.yml
+++ b/.github/workflows/validate_gradle_wrapper.yml
@@ -1,4 +1,4 @@
-# Validates the integrity of the Gradle wrapper
+# Validates the integrity of the Gradle Wrapper
 name: Validate Gradle Wrapper
 
 on:
@@ -13,9 +13,8 @@ on:
     paths:
       - 'gradle/**'
 
-# if a second commit is pushed quickly after the first, cancel the first one's build
 concurrency:
-  group: gradle-wrapper-validation-${{github.head_ref}}
+  group: gradle-wrapper-validation-${{ github.head_ref || github.ref }}
   cancel-in-progress: true
 
 jobs:
@@ -24,7 +23,7 @@ jobs:
 
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Validate Gradle Wrapper
         uses: gradle/wrapper-validation-action@v1

From 0a772ffeb3ca4e049aea3f733f69308acbb59420 Mon Sep 17 00:00:00 2001
From: ALongStringOfNumbers
 <31759736+ALongStringOfNumbers@users.noreply.github.com>
Date: Thu, 28 Dec 2023 18:30:01 -0700
Subject: [PATCH 035/168] Fix a couple incomplete recieveCustomData calls
 (#2322)

---
 .../electric/MetaTileEntityCleanroom.java     | 32 ++++++++++++++++---
 .../MetaTileEntityMultiFluidHatch.java        |  8 +++++
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java
index b9fd8ebf60c..0c34ab575ec 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java
@@ -1,15 +1,31 @@
 package gregtech.common.metatileentities.multi.electric;
 
 import gregtech.api.GTValues;
-import gregtech.api.capability.*;
+import gregtech.api.capability.GregtechDataCodes;
+import gregtech.api.capability.GregtechTileCapabilities;
+import gregtech.api.capability.IEnergyContainer;
+import gregtech.api.capability.IMufflerHatch;
+import gregtech.api.capability.IWorkable;
 import gregtech.api.capability.impl.CleanroomLogic;
 import gregtech.api.capability.impl.EnergyContainerList;
 import gregtech.api.metatileentity.IDataInfoProvider;
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.SimpleGeneratorMetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
-import gregtech.api.metatileentity.multiblock.*;
-import gregtech.api.pattern.*;
+import gregtech.api.metatileentity.multiblock.CleanroomType;
+import gregtech.api.metatileentity.multiblock.FuelMultiblockController;
+import gregtech.api.metatileentity.multiblock.ICleanroomProvider;
+import gregtech.api.metatileentity.multiblock.ICleanroomReceiver;
+import gregtech.api.metatileentity.multiblock.IMultiblockPart;
+import gregtech.api.metatileentity.multiblock.MultiblockAbility;
+import gregtech.api.metatileentity.multiblock.MultiblockDisplayText;
+import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase;
+import gregtech.api.pattern.BlockPattern;
+import gregtech.api.pattern.FactoryBlockPattern;
+import gregtech.api.pattern.MultiblockShapeInfo;
+import gregtech.api.pattern.PatternMatchContext;
+import gregtech.api.pattern.PatternStringError;
+import gregtech.api.pattern.TraceabilityPredicate;
 import gregtech.api.util.BlockInfo;
 import gregtech.api.util.GTUtility;
 import gregtech.api.util.TextComponentUtil;
@@ -61,7 +77,13 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
 
 public class MetaTileEntityCleanroom extends MultiblockWithDisplayBase
                                      implements ICleanroomProvider, IWorkable, IDataInfoProvider {
@@ -643,6 +665,8 @@ public void receiveCustomData(int dataId, PacketBuffer buf) {
         if (dataId == GregtechDataCodes.UPDATE_STRUCTURE_SIZE) {
             this.lDist = buf.readInt();
             this.rDist = buf.readInt();
+            this.bDist = buf.readInt();
+            this.fDist = buf.readInt();
             this.hDist = buf.readInt();
         } else if (dataId == GregtechDataCodes.WORKABLE_ACTIVE) {
             this.cleanroomLogic.setActive(buf.readBoolean());
diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java
index cf77abc3bb6..cf053eb8500 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java
@@ -122,6 +122,14 @@ public void receiveInitialSyncData(PacketBuffer buf) {
         this.workingEnabled = buf.readBoolean();
     }
 
+    @Override
+    public void receiveCustomData(int dataId, PacketBuffer buf) {
+        super.receiveCustomData(dataId, buf);
+        if (dataId == GregtechDataCodes.WORKING_ENABLED) {
+            this.workingEnabled = buf.readBoolean();
+        }
+    }
+
     @Override
     public NBTTagCompound writeToNBT(NBTTagCompound data) {
         super.writeToNBT(data);

From b36f25e5ad7cf07d4eb95dd4fe2b398d04376e29 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+techlord22@users.noreply.github.com>
Date: Thu, 28 Dec 2023 20:32:04 -0500
Subject: [PATCH 036/168] fix test and formatting action concurrency groups

---
 .github/workflows/format_java.yml | 2 +-
 .github/workflows/test_java.yml   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/format_java.yml b/.github/workflows/format_java.yml
index e4537200c13..e8d233df439 100644
--- a/.github/workflows/format_java.yml
+++ b/.github/workflows/format_java.yml
@@ -10,7 +10,7 @@ on:
     paths: ['src/main/java/**', 'src/test/**']
 
 concurrency:
-  group: checks-${{ github.head_ref || github.ref }}
+  group: formatting-${{ github.head_ref || github.ref }}
   cancel-in-progress: true
 
 jobs:
diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml
index 4840c9fa34d..11bc42e8067 100644
--- a/.github/workflows/test_java.yml
+++ b/.github/workflows/test_java.yml
@@ -12,7 +12,7 @@ on:
             'gradlew**', 'src/main/resources/*_at.cfg']
 
 concurrency:
-  group: checks-${{ github.head_ref || github.ref }}
+  group: tests-${{ github.head_ref || github.ref }}
   cancel-in-progress: true
 
 jobs:

From 9e63c51d95a3c7a708e744f34843865b57af1729 Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Thu, 28 Dec 2023 19:40:27 -0600
Subject: [PATCH 037/168] Add some GT items to ExtraBees alveary mutator
 (#2315)

---
 .../integration/forestry/ForestryModule.java  | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/main/java/gregtech/integration/forestry/ForestryModule.java b/src/main/java/gregtech/integration/forestry/ForestryModule.java
index edd4080c33b..de316640666 100644
--- a/src/main/java/gregtech/integration/forestry/ForestryModule.java
+++ b/src/main/java/gregtech/integration/forestry/ForestryModule.java
@@ -7,12 +7,14 @@
 import gregtech.api.items.toolitem.ItemGTTool;
 import gregtech.api.modules.GregTechModule;
 import gregtech.api.recipes.machines.RecipeMapScanner;
+import gregtech.api.unification.OreDictUnifier;
 import gregtech.api.unification.material.Material;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.unification.material.event.MaterialEvent;
 import gregtech.api.unification.material.info.MaterialFlags;
 import gregtech.api.unification.material.properties.OreProperty;
 import gregtech.api.unification.material.properties.PropertyKey;
+import gregtech.api.unification.ore.OrePrefix;
 import gregtech.common.items.ToolItems;
 import gregtech.integration.IntegrationModule;
 import gregtech.integration.IntegrationSubmodule;
@@ -25,6 +27,7 @@
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
 import net.minecraft.item.crafting.IRecipe;
 import net.minecraftforge.client.event.ModelRegistryEvent;
 import net.minecraftforge.event.RegistryEvent;
@@ -41,6 +44,8 @@
 import forestry.core.items.IColoredItem;
 import org.jetbrains.annotations.NotNull;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
@@ -160,6 +165,10 @@ public void init(FMLInitializationEvent event) {
             }
         }
 
+        if (Loader.isModLoaded(GTValues.MODID_EB)) {
+            registerAlvearyMutators();
+        }
+
         if (event.getSide() == Side.CLIENT) {
             if (ForestryUtil.apicultureEnabled()) {
                 if (ForestryConfig.enableGTBees) {
@@ -344,4 +353,31 @@ private static void createOreProperty(Material material, Material... byproducts)
         material.setProperty(PropertyKey.ORE, property);
         material.addFlags(MaterialFlags.DISABLE_ORE_BLOCK);
     }
+
+    private static void registerAlvearyMutators() {
+        try {
+            Class mutationHandler = Class.forName("binnie.extrabees.utils.AlvearyMutationHandler");
+            Method method = mutationHandler.getDeclaredMethod("addMutationItem", ItemStack.class, float.class);
+
+            registerAlvearyMutator(method, Materials.Uranium238, 2.0f);
+            registerAlvearyMutator(method, Materials.Uranium235, 4.0f);
+            registerAlvearyMutator(method, Materials.Plutonium241, 6.0f);
+            registerAlvearyMutator(method, Materials.Plutonium239, 8.0f);
+            registerAlvearyMutator(method, Materials.NaquadahEnriched, 10.0f);
+            registerAlvearyMutator(method, Materials.Naquadria, 15.0f);
+        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
+            IntegrationModule.logger.error("Could not register GT Alveary mutators!");
+        }
+    }
+
+    private static void registerAlvearyMutator(Method method, Material material, float chance) {
+        try {
+            ItemStack stack = OreDictUnifier.get(OrePrefix.dust, material);
+            if (stack != ItemStack.EMPTY) {
+                method.invoke(null, stack, chance);
+            }
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            IntegrationModule.logger.error("Could not register GT Alveary mutators!");
+        }
+    }
 }

From f1100a9aa0d454f0e2486218faedd7495521bffc Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Thu, 28 Dec 2023 19:40:47 -0600
Subject: [PATCH 038/168] Update build script version to 1702805890 (#2309)

Co-authored-by: DStrand1 
Co-authored-by: alongstringofnumbers 
---
 build.gradle      | 6 ++++--
 gradle.properties | 4 +++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/build.gradle b/build.gradle
index 29b2ba602bf..913152a71c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-//version: 1702244235
+//version: 1702805890
 /*
  * DO NOT CHANGE THIS FILE!
  * Also, you may replace this file at any time if there is an update available.
@@ -72,6 +72,7 @@ propertyDefaultIfUnset("usesShadowedDependencies", false)
 propertyDefaultIfUnset("minimizeShadowedDependencies", true)
 propertyDefaultIfUnset("relocateShadowedDependencies", true)
 propertyDefaultIfUnset("separateRunDirectories", false)
+propertyDefaultIfUnset("versionDisplayFormat", '$MOD_NAME \u2212 $VERSION')
 propertyDefaultIfUnsetWithEnvVar("modrinthProjectId", "", "MODRINTH_PROJECT_ID")
 propertyDefaultIfUnset("modrinthRelations", "")
 propertyDefaultIfUnsetWithEnvVar("curseForgeProjectId", "", "CURSEFORGE_PROJECT_ID")
@@ -889,7 +890,7 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
             def changelogFile = getChangelog()
             def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
 
-            mainFile.displayName = "${modName}: ${modVersion}"
+            mainFile.displayName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
             mainFile.releaseType = getReleaseType()
             mainFile.changelog = changelogRaw
             mainFile.changelogType = 'markdown'
@@ -929,6 +930,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
     modrinth {
         token = modrinthApiKey.getOrElse('debug_token')
         projectId = modrinthProjectId
+        versionName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
         changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
         versionType = getReleaseType()
         versionNumber = modVersion
diff --git a/gradle.properties b/gradle.properties
index 102a8c549da..36eb31a2b21 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -90,7 +90,9 @@ relocateShadowedDependencies = true
 # Separate run directories into "run/client" for runClient task, and "run/server" for runServer task.
 # Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/"
 separateRunDirectories = false
-
+# The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables.
+# Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse.
+versionDisplayFormat=$MOD_NAME: $VERSION
 
 # Publishing to modrinth requires you to set the MODRINTH_API_KEY environment variable to your current modrinth API token.
 

From 11648558d1a493919e51d4f1c6e63fcb12f2b797 Mon Sep 17 00:00:00 2001
From: "Josiah \"Rebase\" Roberts"
 <37082009+josiah-roberts@users.noreply.github.com>
Date: Fri, 29 Dec 2023 12:19:22 -0600
Subject: [PATCH 039/168] Fix large turbine recipe selection (#2324)

---
 .../LargeTurbineWorkableHandler.java          | 68 +++++++++++++++++--
 1 file changed, 62 insertions(+), 6 deletions(-)

diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java
index 482d6c710b5..db414ae4da7 100644
--- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java
+++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java
@@ -1,6 +1,7 @@
 package gregtech.common.metatileentities.multi.electric.generator;
 
 import gregtech.api.GTValues;
+import gregtech.api.capability.IMultipleTankHandler;
 import gregtech.api.capability.IRotorHolder;
 import gregtech.api.capability.impl.MultiblockFuelRecipeLogic;
 import gregtech.api.metatileentity.multiblock.FuelMultiblockController;
@@ -8,13 +9,20 @@
 import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController;
 import gregtech.api.recipes.Recipe;
 import gregtech.api.recipes.RecipeBuilder;
+import gregtech.api.recipes.RecipeMap;
+import gregtech.api.util.GTUtility;
 
+import net.minecraft.item.ItemStack;
 import net.minecraft.util.math.MathHelper;
 import net.minecraftforge.fluids.FluidStack;
 import net.minecraftforge.fluids.IFluidTank;
 import net.minecraftforge.fluids.capability.IFluidHandler;
+import net.minecraftforge.items.IItemHandlerModifiable;
+
+import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 public class LargeTurbineWorkableHandler extends MultiblockFuelRecipeLogic {
 
@@ -42,7 +50,9 @@ protected void updateRecipeProgress() {
     public FluidStack getInputFluidStack() {
         // Previous Recipe is always null on first world load, so try to acquire a new recipe
         if (previousRecipe == null) {
-            Recipe recipe = findRecipe(Integer.MAX_VALUE, getInputInventory(), getInputTank());
+            // previousRecipe is set whenever a valid recipe is found
+            // if it's not set, find *any* recipe we have at least the base (non-parallel) inputs for
+            Recipe recipe = super.findRecipe(Integer.MAX_VALUE, getInputInventory(), getInputTank());
 
             return recipe == null ? null : getInputTank().drain(
                     new FluidStack(recipe.getFluidInputs().get(0).getInputFluidStack().getFluid(), Integer.MAX_VALUE),
@@ -73,6 +83,53 @@ protected long boostProduction(long production) {
         return 0;
     }
 
+    private int getParallel(Recipe recipe, double totalHolderEfficiencyCoefficient, int turbineMaxVoltage) {
+        return MathHelper.ceil((turbineMaxVoltage - this.excessVoltage) /
+                (Math.abs(recipe.getEUt()) * totalHolderEfficiencyCoefficient));
+    }
+
+    private boolean canDoRecipeWithParallel(Recipe recipe) {
+        IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder();
+        if (rotorHolder == null || !rotorHolder.hasRotor())
+            return false;
+        double totalHolderEfficiencyCoefficient = rotorHolder.getTotalEfficiency() / 100.0;
+        int turbineMaxVoltage = (int) getMaxVoltage();
+        int parallel = getParallel(recipe, totalHolderEfficiencyCoefficient, turbineMaxVoltage);
+
+        FluidStack recipeFluidStack = recipe.getFluidInputs().get(0).getInputFluidStack();
+
+        // Intentionally not using this.getInputFluidStack because that is locked to the previous recipe
+        FluidStack inputFluid = getInputTank().drain(
+                new FluidStack(recipeFluidStack.getFluid(), Integer.MAX_VALUE),
+                false);
+        return inputFluid != null && inputFluid.amount >= recipeFluidStack.amount * parallel;
+    }
+
+    @Override
+    protected boolean checkPreviousRecipe() {
+        return super.checkPreviousRecipe() && canDoRecipeWithParallel(this.previousRecipe);
+    }
+
+    @Override
+    protected @Nullable Recipe findRecipe(long maxVoltage, IItemHandlerModifiable inputs,
+                                          IMultipleTankHandler fluidInputs) {
+        RecipeMap map = getRecipeMap();
+        if (map == null || !isRecipeMapValid(map)) {
+            return null;
+        }
+
+        final List items = GTUtility.itemHandlerToList(inputs).stream().filter(s -> !s.isEmpty()).collect(
+                Collectors.toList());
+        final List fluids = GTUtility.fluidHandlerToList(fluidInputs).stream()
+                .filter(f -> f != null && f.amount != 0)
+                .collect(Collectors.toList());
+
+        return map.find(items, fluids, recipe -> {
+            if (recipe.getEUt() > maxVoltage) return false;
+            return recipe.matches(false, inputs, fluidInputs) && this.canDoRecipeWithParallel(recipe);
+        });
+    }
+
     @Override
     protected boolean prepareRecipe(Recipe recipe) {
         IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder();
@@ -83,13 +140,12 @@ protected boolean prepareRecipe(Recipe recipe) {
         FluidStack recipeFluidStack = recipe.getFluidInputs().get(0).getInputFluidStack();
         int parallel = 0;
 
-        if (excessVoltage >= turbineMaxVoltage) {
-            excessVoltage -= turbineMaxVoltage;
+        if (this.excessVoltage >= turbineMaxVoltage) {
+            this.excessVoltage -= turbineMaxVoltage;
         } else {
             double holderEfficiency = rotorHolder.getTotalEfficiency() / 100.0;
             // get the amount of parallel required to match the desired output voltage
-            parallel = MathHelper.ceil((turbineMaxVoltage - excessVoltage) /
-                    (Math.abs(recipe.getEUt()) * holderEfficiency));
+            parallel = getParallel(recipe, holderEfficiency, turbineMaxVoltage);
 
             // Null check fluid here, since it can return null on first join into world or first form
             FluidStack inputFluid = getInputFluidStack();
@@ -98,7 +154,7 @@ protected boolean prepareRecipe(Recipe recipe) {
             }
 
             // this is necessary to prevent over-consumption of fuel
-            excessVoltage += (int) (parallel * Math.abs(recipe.getEUt()) * holderEfficiency - turbineMaxVoltage);
+            this.excessVoltage += (int) (parallel * Math.abs(recipe.getEUt()) * holderEfficiency - turbineMaxVoltage);
         }
 
         // rebuild the recipe and adjust voltage to match the turbine

From fb88041caf78c466b42ac938cab5c5ff4d9a9ef5 Mon Sep 17 00:00:00 2001
From: "Josiah \"Rebase\" Roberts"
 <37082009+josiah-roberts@users.noreply.github.com>
Date: Fri, 29 Dec 2023 12:53:58 -0600
Subject: [PATCH 040/168] Use locale formatting where possible in WAILA and The
 One Probe (#2327)

---
 .../hwyla/provider/ConverterDataProvider.java       | 11 +++++++----
 .../hwyla/provider/DiodeDataProvider.java           |  7 +++++--
 .../hwyla/provider/PrimitivePumpDataProvider.java   |  4 +++-
 .../hwyla/provider/RecipeLogicDataProvider.java     |  5 +++--
 .../hwyla/provider/SteamBoilerDataProvider.java     |  4 +++-
 .../hwyla/provider/TransformerDataProvider.java     |  5 +++--
 .../theoneprobe/provider/ConverterInfoProvider.java | 13 +++++++++----
 .../theoneprobe/provider/CoverInfoProvider.java     |  5 +++--
 .../provider/ElectricContainerInfoProvider.java     |  5 +++--
 .../provider/LaserContainerInfoProvider.java        |  6 ++++--
 .../provider/PrimitivePumpInfoProvider.java         |  5 ++++-
 .../provider/RecipeLogicInfoProvider.java           |  7 +++++--
 .../provider/SteamBoilerInfoProvider.java           |  4 +++-
 .../provider/TransformerInfoProvider.java           |  5 +++--
 .../theoneprobe/provider/WorkableInfoProvider.java  |  6 ++++--
 15 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java
index 341334681c7..593832936cc 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/ConverterDataProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.capability.FeCompat;
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.converter.ConverterTrait;
 
 import net.minecraft.client.resources.I18n;
@@ -67,19 +68,21 @@ protected NBTTagCompound getNBTData(ConverterTrait capability, NBTTagCompound ta
                 tooltip.add(I18n.format("gregtech.top.convert_fe"));
                 if (accessor.getSide() == frontFacing) {
                     tooltip.add(I18n.format("gregtech.top.transform_output") + " " + voltageName +
-                            TextFormatting.RESET + " (" + amperage + "A)");
+                            TextFormatting.RESET + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
                 } else {
                     tooltip.add(I18n.format("gregtech.top.transform_input") + " " +
-                            FeCompat.toFe(voltage * amperage, FeCompat.ratio(true)) + " FE");
+                            TextFormattingUtil.formatNumbers(FeCompat.toFe(voltage * amperage, FeCompat.ratio(true))) +
+                            " FE");
                 }
             } else {
                 tooltip.add(I18n.format("gregtech.top.convert_eu"));
                 if (accessor.getSide() == frontFacing) {
                     tooltip.add(I18n.format("gregtech.top.transform_output") + " " +
-                            FeCompat.toFe(voltage * amperage, FeCompat.ratio(false)) + " FE");
+                            TextFormattingUtil.formatNumbers(FeCompat.toFe(voltage * amperage, FeCompat.ratio(false))) +
+                            " FE");
                 } else {
                     tooltip.add(I18n.format("gregtech.top.transform_input") + " " + voltageName + TextFormatting.RESET +
-                            " (" + amperage + "A)");
+                            " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
                 }
             }
         }
diff --git a/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java
index 1000a11ff55..69e38bfaad7 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/DiodeDataProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.capability.IEnergyContainer;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.electric.MetaTileEntityDiode;
 
 import net.minecraft.client.resources.I18n;
@@ -59,9 +60,11 @@ protected NBTTagCompound getNBTData(IEnergyContainer capability, NBTTagCompound
             final EnumFacing frontFacing = EnumFacing.byIndex(tag.getInteger("FrontFacing"));
 
             if (accessor.getSide() == frontFacing) { // output side
-                tooltip.add(I18n.format("gregtech.top.transform_output") + " " + outputAmperage + " A");
+                tooltip.add(I18n.format("gregtech.top.transform_output") + " " +
+                        TextFormattingUtil.formatNumbers(outputAmperage) + " A");
             } else {
-                tooltip.add(I18n.format("gregtech.top.transform_input") + " " + inputAmperage + " A");
+                tooltip.add(I18n.format("gregtech.top.transform_input") + " " +
+                        TextFormattingUtil.formatNumbers(inputAmperage) + " A");
             }
         }
         return tooltip;
diff --git a/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java
index 4af2e2f8915..3598647818f 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/PrimitivePumpDataProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.metatileentity.multiblock.IPrimitivePump;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.client.resources.I18n;
 import net.minecraft.entity.player.EntityPlayerMP;
@@ -58,7 +59,8 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
         if (accessor.getNBTData().hasKey("gregtech.IPrimitivePump")) {
             NBTTagCompound tag = accessor.getNBTData().getCompoundTag("gregtech.IPrimitivePump");
             int production = tag.getInteger("Production");
-            tooltip.add(I18n.format("gregtech.top.primitive_pump_production") + " " + TextFormatting.AQUA + production +
+            tooltip.add(I18n.format("gregtech.top.primitive_pump_production") + " " + TextFormatting.AQUA +
+                    TextFormattingUtil.formatNumbers(production) +
                     TextFormatting.RESET + " L/s");
         }
         return tooltip;
diff --git a/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java
index f1a2a6b5a4c..655dd57aa20 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java
@@ -9,6 +9,7 @@
 import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler;
 
 import net.minecraft.client.resources.I18n;
@@ -72,7 +73,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     MetaTileEntity mte = gtte.getMetaTileEntity();
                     if (mte instanceof SteamMetaTileEntity || mte instanceof MetaTileEntityLargeBoiler ||
                             mte instanceof RecipeMapSteamMultiblockController) {
-                        endText = ": " + absEUt + TextFormatting.RESET + " L/t " +
+                        endText = ": " + TextFormattingUtil.formatNumbers(absEUt) + TextFormatting.RESET + " L/t " +
                                 I18n.format(Materials.Steam.getUnlocalizedName());
                     }
                     AbstractRecipeLogic arl = mte.getRecipeLogic();
@@ -81,7 +82,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     }
                 }
                 if (endText == null) {
-                    endText = ": " + absEUt + TextFormatting.RESET + " EU/t (" +
+                    endText = ": " + TextFormattingUtil.formatNumbers(absEUt) + TextFormatting.RESET + " EU/t (" +
                             GTValues.VNF[GTUtility.getTierByVoltage(absEUt)] + TextFormatting.RESET + ")";
                 }
 
diff --git a/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java
index 85a3f738ca0..0baaab2927f 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.unification.material.Materials;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.steam.boiler.SteamBoiler;
 
 import net.minecraft.client.resources.I18n;
@@ -65,7 +66,8 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
 
                 // Creating steam
                 if (steamRate > 0 && hasWater) {
-                    tooltip.add(I18n.format("gregtech.top.energy_production") + ": " + (steamRate / 10) + " L/t " +
+                    tooltip.add(I18n.format("gregtech.top.energy_production") + ": " +
+                            TextFormattingUtil.formatNumbers(steamRate / 10) + " L/t " +
                             I18n.format(Materials.Steam.getUnlocalizedName()));
                 }
 
diff --git a/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java
index 49da30bf2da..e54792f8139 100644
--- a/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java
+++ b/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.capability.IEnergyContainer;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.electric.MetaTileEntityTransformer;
 
 import net.minecraft.client.resources.I18n;
@@ -82,7 +83,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     .append(GTValues.VNF[GTUtility.getTierByVoltage(inputVoltage)])
                     .append(TextFormatting.RESET)
                     .append(" (")
-                    .append(inputAmperage)
+                    .append(TextFormattingUtil.formatNumbers(inputAmperage))
                     .append("A)");
 
             StringBuilder output = new StringBuilder()
@@ -90,7 +91,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai
                     .append(GTValues.VNF[GTUtility.getTierByVoltage(outputVoltage)])
                     .append(TextFormatting.RESET)
                     .append(" (")
-                    .append(outputAmperage)
+                    .append(TextFormattingUtil.formatNumbers(outputAmperage))
                     .append("A)");
 
             // Step Up/Step Down line
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java
index 4a635e9058a..2ef4b0e3e05 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java
@@ -5,6 +5,7 @@
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.converter.ConverterTrait;
 
 import net.minecraft.entity.player.EntityPlayer;
@@ -45,18 +46,22 @@ protected void addProbeInfo(@NotNull ConverterTrait capability, @NotNull IProbeI
         if (capability.isFeToEu()) {
             if (data.getSideHit() == facing) {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_output*} " + voltageN +
-                        TextFormatting.GREEN + " (" + amperage + "A)");
+                        TextFormatting.GREEN + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
             } else {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_input*} " + TextFormatting.RED +
-                        FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(true)) + " FE");
+                        TextFormattingUtil.formatNumbers(
+                                FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(true))) +
+                        " FE");
             }
         } else {
             if (data.getSideHit() == facing) {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_output*} " + TextFormatting.RED +
-                        FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(false)) + " FE");
+                        TextFormattingUtil.formatNumbers(
+                                FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(false))) +
+                        " FE");
             } else {
                 probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_input*} " + voltageN +
-                        TextFormatting.GREEN + " (" + amperage + "A)");
+                        TextFormatting.GREEN + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)");
             }
         }
     }
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java
index 645e6774d3b..6656fcc9d7e 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java
@@ -204,7 +204,8 @@ private static void transferRateText(@NotNull IProbeInfo probeInfo, @NotNull IIO
     private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull TransferMode mode,
                                          @NotNull String rateUnit, int rate, boolean hasFilter) {
         String text = TextStyleClass.OK + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC;
-        if (!hasFilter && mode != TransferMode.TRANSFER_ANY) text += TextStyleClass.LABEL + " " + rate + rateUnit;
+        if (!hasFilter && mode != TransferMode.TRANSFER_ANY)
+            text += TextStyleClass.LABEL + " " + TextFormattingUtil.formatNumbers(rate) + rateUnit;
         probeInfo.text(text);
     }
 
@@ -220,7 +221,7 @@ private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull Tra
     private static void voidingText(@NotNull IProbeInfo probeInfo, @NotNull VoidingMode mode, @NotNull String unit,
                                     int amount, boolean hasFilter) {
         String text = TextFormatting.RED + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC;
-        if (mode != VoidingMode.VOID_ANY && !hasFilter) text += " " + amount + unit;
+        if (mode != VoidingMode.VOID_ANY && !hasFilter) text += " " + TextFormattingUtil.formatNumbers(amount) + unit;
         probeInfo.text(text);
     }
 
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java
index 7252ebbca23..4b2e970d7c6 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.capability.GregtechCapabilities;
 import gregtech.api.capability.IEnergyContainer;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
@@ -36,9 +37,9 @@ protected void addProbeInfo(@NotNull IEnergyContainer capability, @NotNull IProb
         long maxStorage = capability.getEnergyCapacity();
         if (maxStorage == 0) return; // do not add empty max storage progress bar
         probeInfo.progress(capability.getEnergyStored(), maxStorage, probeInfo.defaultProgressStyle()
-                .suffix(" / " + maxStorage + " EU")
+                .suffix(" / " + TextFormattingUtil.formatNumbers(maxStorage) + " EU")
                 .filledColor(0xFFEEE600)
                 .alternateFilledColor(0xFFEEE600)
-                .borderColor(0xFF555555));
+                .borderColor(0xFF555555).numberFormat(mcjty.theoneprobe.api.NumberFormat.COMMAS));
     }
 }
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java
index d75c6a7c8eb..404bf223680 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java
@@ -3,6 +3,7 @@
 import gregtech.api.GTValues;
 import gregtech.api.capability.GregtechTileCapabilities;
 import gregtech.api.capability.ILaserContainer;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
@@ -10,6 +11,7 @@
 
 import mcjty.theoneprobe.api.IProbeHitData;
 import mcjty.theoneprobe.api.IProbeInfo;
+import mcjty.theoneprobe.api.NumberFormat;
 import org.jetbrains.annotations.NotNull;
 
 public class LaserContainerInfoProvider extends CapabilityInfoProvider {
@@ -31,10 +33,10 @@ protected void addProbeInfo(ILaserContainer capability, IProbeInfo probeInfo, En
         long maxStorage = capability.getEnergyCapacity();
         if (maxStorage == 0) return; // do not add empty max storage progress bar
         probeInfo.progress(capability.getEnergyStored(), maxStorage, probeInfo.defaultProgressStyle()
-                .suffix(" / " + maxStorage + " EU")
+                .suffix(" / " + TextFormattingUtil.formatNumbers(maxStorage) + " EU")
                 .filledColor(0xFFEEE600)
                 .alternateFilledColor(0xFFEEE600)
-                .borderColor(0xFF555555));
+                .borderColor(0xFF555555).numberFormat(NumberFormat.COMMAS));
     }
 
     @Override
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java
index ea20f8be8a8..3c7d3d79004 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.metatileentity.multiblock.IPrimitivePump;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.entity.player.EntityPlayer;
@@ -32,7 +33,9 @@ public void addProbeInfo(@NotNull ProbeMode mode, @NotNull IProbeInfo probeInfo,
             if (metaTileEntity instanceof IPrimitivePump) {
                 probeInfo.text(
                         TextStyleClass.INFO + "{*gregtech.top.primitive_pump_production*} " + TextFormatting.AQUA +
-                                ((IPrimitivePump) metaTileEntity).getFluidProduction() + TextFormatting.RESET + " L/s");
+                                TextFormattingUtil
+                                        .formatNumbers(((IPrimitivePump) metaTileEntity).getFluidProduction()) +
+                                TextFormatting.RESET + " L/s");
             }
         }
     }
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java
index 8ea1a0ac3c7..3a60fab7db6 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java
@@ -10,6 +10,7 @@
 import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController;
 import gregtech.api.unification.material.Materials;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler;
 
 import net.minecraft.entity.player.EntityPlayer;
@@ -53,14 +54,16 @@ protected void addProbeInfo(@NotNull AbstractRecipeLogic capability, @NotNull IP
                 MetaTileEntity mte = gtTileEntity.getMetaTileEntity();
                 if (mte instanceof SteamMetaTileEntity || mte instanceof MetaTileEntityLargeBoiler ||
                         mte instanceof RecipeMapSteamMultiblockController) {
-                    text = TextFormatting.AQUA.toString() + absEUt + TextStyleClass.INFO + " L/t {*" +
+                    text = TextFormatting.AQUA.toString() + TextFormattingUtil.formatNumbers(absEUt) +
+                            TextStyleClass.INFO + " L/t {*" +
                             Materials.Steam.getUnlocalizedName() + "*}";
                 }
             }
             if (text == null) {
                 // Default behavior, if this TE is not a steam machine (or somehow not instanceof
                 // IGregTechTileEntity...)
-                text = TextFormatting.RED.toString() + absEUt + TextStyleClass.INFO + " EU/t" + TextFormatting.GREEN +
+                text = TextFormatting.RED.toString() + TextFormattingUtil.formatNumbers(absEUt) + TextStyleClass.INFO +
+                        " EU/t" + TextFormatting.GREEN +
                         " (" + GTValues.VNF[GTUtility.getTierByVoltage(absEUt)] + TextFormatting.GREEN + ")";
             }
 
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java
index 4ccdc7125d0..248d0fc1d02 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.unification.material.Materials;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.steam.boiler.SteamBoiler;
 
 import net.minecraft.block.state.IBlockState;
@@ -36,7 +37,8 @@ public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, EntityPlayer play
                         // Creating steam
                         if (steamOutput > 0 && boiler.hasWater()) {
                             probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_production*} " +
-                                    TextFormatting.AQUA + (steamOutput / 10) + TextStyleClass.INFO + " L/t" + " {*" +
+                                    TextFormatting.AQUA + TextFormattingUtil.formatNumbers(steamOutput / 10) +
+                                    TextStyleClass.INFO + " L/t" + " {*" +
                                     Materials.Steam.getUnlocalizedName() + "*}");
                         }
 
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java
index cf77786cc15..0cf94adc4bd 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java
@@ -5,6 +5,7 @@
 import gregtech.api.metatileentity.MetaTileEntity;
 import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
 import gregtech.api.util.GTUtility;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.common.metatileentities.electric.MetaTileEntityTransformer;
 
 import net.minecraft.entity.player.EntityPlayer;
@@ -33,14 +34,14 @@ protected void addProbeInfo(@NotNull IEnergyContainer capability, @NotNull IProb
                         .append(GTValues.VNF[GTUtility.getTierByVoltage(capability.getInputVoltage())])
                         .append(TextFormatting.GREEN)
                         .append(" (")
-                        .append(capability.getInputAmperage())
+                        .append(TextFormattingUtil.formatNumbers(capability.getInputAmperage()))
                         .append("A)");
 
                 StringBuilder output = new StringBuilder()
                         .append(GTValues.VNF[GTUtility.getTierByVoltage(capability.getOutputVoltage())])
                         .append(TextFormatting.GREEN)
                         .append(" (")
-                        .append(capability.getOutputAmperage())
+                        .append(TextFormattingUtil.formatNumbers(capability.getOutputAmperage()))
                         .append("A)");
 
                 // Step Up/Step Down line
diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java
index 5d3c500e81e..ac6254aa8b5 100644
--- a/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java
+++ b/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java
@@ -4,6 +4,7 @@
 import gregtech.api.capability.GregtechTileCapabilities;
 import gregtech.api.capability.IWorkable;
 import gregtech.api.capability.impl.ComputationRecipeLogic;
+import gregtech.api.util.TextFormattingUtil;
 
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.tileentity.TileEntity;
@@ -11,6 +12,7 @@
 
 import mcjty.theoneprobe.api.IProbeHitData;
 import mcjty.theoneprobe.api.IProbeInfo;
+import mcjty.theoneprobe.api.NumberFormat;
 import org.jetbrains.annotations.NotNull;
 
 public class WorkableInfoProvider extends CapabilityInfoProvider {
@@ -52,7 +54,7 @@ protected void addProbeInfo(@NotNull IWorkable capability, @NotNull IProbeInfo p
         } else {
             currentProgress = Math.round(currentProgress / 20.0F);
             maxProgress = Math.round(maxProgress / 20.0F);
-            text = " / " + maxProgress + " s";
+            text = " / " + TextFormattingUtil.formatNumbers(maxProgress) + " s";
         }
 
         if (maxProgress > 0) {
@@ -61,7 +63,7 @@ protected void addProbeInfo(@NotNull IWorkable capability, @NotNull IProbeInfo p
                     .suffix(text)
                     .filledColor(color)
                     .alternateFilledColor(color)
-                    .borderColor(0xFF555555));
+                    .borderColor(0xFF555555).numberFormat(NumberFormat.COMMAS));
         }
     }
 }

From 230fc8029d526b1cb062cce8df2132a50f212cbd Mon Sep 17 00:00:00 2001
From: "Josiah \"Rebase\" Roberts"
 <37082009+josiah-roberts@users.noreply.github.com>
Date: Sun, 31 Dec 2023 12:52:13 -0600
Subject: [PATCH 041/168] Use EU/t for digital interface (#2329)

---
 .../java/gregtech/common/covers/CoverDigitalInterface.java | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java
index 0a04343acde..7455688d164 100644
--- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java
+++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java
@@ -16,6 +16,7 @@
 import gregtech.api.metatileentity.multiblock.MultiblockControllerBase;
 import gregtech.api.util.GTLog;
 import gregtech.api.util.Position;
+import gregtech.api.util.TextFormattingUtil;
 import gregtech.client.renderer.texture.Textures;
 import gregtech.client.utils.RenderUtil;
 import gregtech.common.terminal.app.prospector.widget.WidgetOreList;
@@ -1046,9 +1047,11 @@ private void renderEnergyMode() {
         }
         RenderUtil.renderLineChart(inputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFF03FF00);
         RenderUtil.renderLineChart(outputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFFFF2F39);
-        RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00, "EU I: " + energyInputPerDur + "EU/s",
+        RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00,
+                "EU I: " + TextFormattingUtil.formatNumbers(energyInputPerDur / 20) + "EU/t",
                 false);
-        RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000, "EU O: " + energyOutputPerDur + "EU/s",
+        RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000,
+                "EU O: " + TextFormattingUtil.formatNumbers(energyOutputPerDur / 20) + "EU/t",
                 false);
         // Bandaid fix to prevent overflowing renders when dealing with items that cause long overflow, ie Ultimate
         // Battery

From 2e64d06fd8194743a3680e4ebeb276778d1a1846 Mon Sep 17 00:00:00 2001
From: marisathewitch 
Date: Mon, 1 Jan 2024 06:16:59 +0400
Subject: [PATCH 042/168] Update ru_ru.lang (#2307)

---
 .../resources/assets/gregtech/lang/ru_ru.lang | 266 +++++++++---------
 1 file changed, 136 insertions(+), 130 deletions(-)

diff --git a/src/main/resources/assets/gregtech/lang/ru_ru.lang b/src/main/resources/assets/gregtech/lang/ru_ru.lang
index 349a33f2169..5341d2fadb8 100644
--- a/src/main/resources/assets/gregtech/lang/ru_ru.lang
+++ b/src/main/resources/assets/gregtech/lang/ru_ru.lang
@@ -42,8 +42,8 @@ gregtech.multiblock.steam.low_steam=Недостаточно пара для р
 gregtech.multiblock.steam.steam_stored=Пар: %s / %s mB
 gregtech.machine.steam_hatch.name=Паровой люк
 gregtech.machine.steam.steam_hatch.tooltip=§eПринимает жидкости: §fПар
-gregtech.machine.steam_import_bus.name=Входной предметный люк (Пар)
-gregtech.machine.steam_export_bus.name=Выходной предметный люк (Пар)
+gregtech.machine.steam_import_bus.name=Паровой входной люк
+gregtech.machine.steam_export_bus.name=Паровой выходной люк
 gregtech.machine.steam_bus.tooltip=Не работает с электрическими многоблочными структурами
 gregtech.machine.steam_oven.name=Паровая мультиплавильня
 gregtech.multiblock.steam_oven.description=Мультиплавильня в паровой эпохе. Требует как минимум 6 бронзовых машинных корпусов. Может использовать только паровые люки. Паровой люк должен находится на нижнем слое и он может быть только один.
@@ -52,7 +52,7 @@ gregtech.multiblock.steam_.duration_modifier=Работает в §f1.5x §7ра
 gregtech.top.working_disabled=Работа остановлена
 gregtech.top.energy_consumption=Использует
 gregtech.top.energy_production=Производит
-gregtech.top.transform_up=§cПовышает§r
+gregtech.top.transform_up=Повышает
 gregtech.top.transform_down=§aПонижает§r
 gregtech.top.transform_input=Вход:
 gregtech.top.transform_output=Выход:
@@ -102,7 +102,7 @@ gregtech.multiblock.extreme_combustion_engine.description=Улучшенный 
 gregtech.multiblock.distillation_tower.description=Ректификационная колонна - представляет собой многоблочную структуру, используемую для перегонки различных типов нефти и некоторых их побочных продуктов.
 gregtech.multiblock.electric_blast_furnace.description=Электрическая доменная печь (ЭДП) - это многоблочная структура, используемая для выплавки сплавов, приготовления металлов и переработки руд. Она необходима для получения высокоуровневых сплавов и металлов, таких как алюминий, нержавеющая сталь и титан, сплав наквада.
 gregtech.multiblock.multi_furnace.description=Мульти-плавильный завод - это многоблочная структура, используемая для одновременной выплавки большого количества изделий. Различные уровни катушек обеспечивают увеличение скорости и повышение энергоэффективности. 32 - это базовое значение предметов, выплавляемых за одну операцию, и его можно умножить, используя катушки более высокого уровня.
-gregtech.multiblock.large_boiler.description=Большой котел - представляет собой многоблочную структуру, которая генерируют пар из источника энергии и воды. Обычно либо твердое топливо, либо горючая жидкость высокой плотности действует как источник энергии для большого котла. Уровни отличаются только количеством вырабатываемого пара.
+gregtech.multiblock.large_boiler.description=Большой котел - представляет собой многоблочную структуру, которая генерируют пар из источника энергии и воды. Обычно либо твердое топливо, либо горючая жидкость высокой плотности действует как источник энергии для большого котла. Уровни отличаются только кол-вом вырабатываемого пара.
 gregtech.multiblock.large_turbine.description=Большая турбина - это многоблочная структура, которые вырабатывают энергию из пара, газов и плазмы, вращая ротор турбины. Выход энергии зависит от КПД ротора и текущей скорости турбины.
 gregtech.multiblock.assembly_line.description=Сборочная линия представляет собой большую многоблочную конструкцию, состоящую из 5-16 «кусочков». Теоретически это большая сборочная машина, используемая для создания продвинутых компонентов для крафта.
 gregtech.multiblock.fusion_reactor.luv.description=Термоядерный реактор модель 1 - это большая многоблочная структура использующаяся для термоядерного синтеза двух элементов в один. Может использовать LuV+ энергетические разъемы. За каждый энергетический разъём, внутренний буфер увеличивается на 10млн. EU, максимум энергии для старта 160млн. EU.
@@ -110,17 +110,17 @@ gregtech.multiblock.fusion_reactor.zpm.description=Термоядерный ре
 gregtech.multiblock.fusion_reactor.uv.description=Термоядерный реактор модель 3 - это большая многоблочная структура использующаяся для термоядерного синтеза двух элементов в один. Может использовать UV+ энергетические разъемы. За каждый энергетический разъём, внутренний буфер увеличивается на 40млн. EU, максимум энергии для старта 640млн. EU.
 gregtech.multiblock.fusion_reactor.heat=Нагрев: %d
 gregtech.multiblock.large_chemical_reactor.description=Многоблочная версия химического реактора выполняющий операции в больших объёмах с удвоенной эффективностью. Ускорение умножает скорость и энергию на 4. Для мультиблочной структуры требуется ровно 1 блок купроникелевой катушки, который должен быть размещен рядом с корпусом ПТФЭ трубы, расположенным в центре.
-gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая количество воды от уровня. Выполняется по формуле: Коэффициент биома * Множитель люка.
-gregtech.multiblock.primitive_water_pump.extra1=Коэффициент биома:/n  Океан, Река: 1000 л/с/н  Болото: 800 л/с/н  Джунгли: 350 л/с/н  Снежный: 300 л/с/н  Равнины, Лес: 250 л/с/н  Тайга : 175 л/с/н  Пляж: 170 л/с/н  Другое: 100 л/с
+gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая кол-во воды от уровня. Выполняется по формуле: Коэф. биома * Множитель люка.
+gregtech.multiblock.primitive_water_pump.extra1=Коэф. биома:/n  Океан, Река: 1000 Л/с/n  Болото: 800 Л/с/n  Джунгли: 350 Л/с/n  Снежный: 300 Л/с/н  Равнины, Лес: 250 Л/с/n  Тайга : 175 Л/с/n  Пляж: 170 Л/с/n  Другое: 100 Л/с
 gregtech.multiblock.primitive_water_pump.extra2=Множители люка:/n  Люк насоса: 1x/n  Выходной люк ULV: 2x/n  LV Выходной люк: 4xn/nВо время дождя в биомах работы насоса добыча воды будет увеличена на 50%%.
 gregtech.multiblock.processing_array.description=Массив машин объединяет до 16 одноблочных машин в одном многоблоке.
 gregtech.multiblock.advanced_processing_array.description=Массив машин объединяет до 64 одноблочных машин в одном многоблоке.
 item.invalid.name=Недопустимый предмет
 fluid.empty=Пусто
-gregtech.tooltip.hold_shift=Зажмите SHIFT для дополнительной информации
-gregtech.tooltip.hold_ctrl=Нажмите CTRL, чтобы увидеть больше информации
-gregtech.tooltip.fluid_pipe_hold_shift=Зажмите SHIFT что-бы посмотреть Информацию о Хранимой Жидкости
-gregtech.tooltip.tool_fluid_hold_shift=Зажмите SHIFT что-бы посмотреть Информацию о Инструменте или Хранимой Жидкости
+gregtech.tooltip.hold_shift=Зажмите SHIFT для Информации
+gregtech.tooltip.hold_ctrl=Зажмите CTRL для Информации
+gregtech.tooltip.fluid_pipe_hold_shift=Зажмите SHIFT для Информации о Жидкости
+gregtech.tooltip.tool_fluid_hold_shift=Зажмите SHIFT для Информации о Инструменте или Жидкости
 metaitem.generic.fluid_container.tooltip=%d/%dЛ %s
 metaitem.generic.electric_item.tooltip=%d/%d EU - Уровень §e%d
 metaitem.electric.discharge_mode.enabled=§eРежим разрядки Включен
@@ -130,19 +130,19 @@ metaitem.dust.tooltip.purify=Бросьте в котел, чтобы получ
 metaitem.crushed.tooltip.purify=Бросьте в котел, чтобы получить очищенную руду
 metaitem.int_circuit.configuration=§aКонфигурация: §f%d§7
 metaitem.credit.copper.name=Медный кредит
-metaitem.credit.copper.tooltip=0,125 кредита
+metaitem.credit.copper.tooltip=0,125 Кредита
 metaitem.credit.cupronickel.name=Купроникелевый кредит
-metaitem.credit.cupronickel.tooltip=1 кредит
+metaitem.credit.cupronickel.tooltip=1 Кредит
 metaitem.credit.silver.name=Серебряный кредит
-metaitem.credit.silver.tooltip=8 кредитов
+metaitem.credit.silver.tooltip=8 Кредитов
 metaitem.credit.gold.name=Золотой кредит
-metaitem.credit.gold.tooltip=64 кредита
+metaitem.credit.gold.tooltip=64 Кредита
 metaitem.credit.platinum.name=Платиновый кредит
-metaitem.credit.platinum.tooltip=512 кредитов
+metaitem.credit.platinum.tooltip=512 Кредитов
 metaitem.credit.osmium.name=Осмиевый кредит
-metaitem.credit.osmium.tooltip=4096 кредитов
+metaitem.credit.osmium.tooltip=4096 Кредитов
 metaitem.credit.naquadah.name=Наквадовый кредит
-metaitem.credit.naquadah.tooltip=32768 кредитов
+metaitem.credit.naquadah.tooltip=32768 Кредитов
 metaitem.credit.neutronium.name=Нейтрониевый кредит
 metaitem.credit.neutronium.tooltip=262144 Кредитов
 metaitem.coin.gold.ancient.name=Древняя золотая монета
@@ -164,7 +164,7 @@ metaitem.nano_saber.tooltip=Ryujin no ken wo kurae!
 metaitem.shape.mold.plate.name=Форма (Пластина)
 metaitem.shape.mold.plate.tooltip=Форма для изготовления пластин
 metaitem.shape.mold.casing.name=Форма (Корпус)
-metaitem.shape.mold.casing.tooltip=Форма для изготовления оболочек
+metaitem.shape.mold.casing.tooltip=Форма для изготовления корпусов
 metaitem.shape.mold.gear.name=Форма (Шестерня)
 metaitem.shape.mold.gear.tooltip=Форма для изготовления шестерней
 metaitem.shape.mold.credit.name=Форма (Чеканка)
@@ -177,7 +177,7 @@ metaitem.shape.mold.ball.name=Форма (Шар)
 metaitem.shape.mold.ball.tooltip=Форма для изготовления шариков
 metaitem.shape.mold.block.name=Форма (Блок)
 metaitem.shape.mold.block.tooltip=Форма для изготовления блоков
-metaitem.shape.mold.nugget.name=Форма (Самородки)
+metaitem.shape.mold.nugget.name=Форма (Самородок)
 metaitem.shape.mold.nugget.tooltip=Форма для изготовления самородков
 metaitem.shape.mold.cylinder.name=Форма (Цилиндр)
 metaitem.shape.mold.cylinder.tooltip=Форма для формирования цилиндров
@@ -186,7 +186,7 @@ metaitem.shape.mold.anvil.tooltip=Форма для формирования н
 metaitem.shape.mold.name.name=Форма (Имя)
 metaitem.shape.mold.name.tooltip=Форма для наименования предметов (переименуйте форму с помощью наковальни)
 metaitem.shape.mold.gear.small.name=Форма (Малая шестерня)
-metaitem.shape.mold.gear.small.tooltip=Форма для изготовления маленьких зубчатых колес
+metaitem.shape.mold.gear.small.tooltip=Форма для изготовления маленьких шестерней
 metaitem.shape.mold.rotor.name=Форма (Ротор)
 metaitem.shape.mold.rotor.tooltip=Форма для изготовления роторов
 metaitem.shape.extruder.plate.name=Форма экструдера (Пластина)
@@ -197,16 +197,16 @@ metaitem.shape.extruder.bolt.name=Форма экструдера (Болт)
 metaitem.shape.extruder.bolt.tooltip=Форма экструдера для изготовления болтов
 metaitem.shape.extruder.ring.name=Форма экструдера (Кольцо)
 metaitem.shape.extruder.ring.tooltip=Форма экструдера для изготовления колец
-metaitem.shape.extruder.cell.name=Форма экструдера (Ячейка)
-metaitem.shape.extruder.cell.tooltip=Форма экструдера для изготовления клеток
+metaitem.shape.extruder.cell.name=Форма экструдера (Капсула)
+metaitem.shape.extruder.cell.tooltip=Форма экструдера для изготовления капсул
 metaitem.shape.extruder.ingot.name=Форма экструдера (Слиток)
-metaitem.shape.extruder.ingot.tooltip=Форма экструдера, подожди, мы не можем просто использовать печь?
+metaitem.shape.extruder.ingot.tooltip=Форма экструдера, подожди, может просто использовать печь?
 metaitem.shape.extruder.wire.name=Форма экструдера (Проволока)
 metaitem.shape.extruder.wire.tooltip=Форма экструдера для изготовления проводов
 metaitem.shape.extruder.casing.name=Форма экструдера (Корпус)
-metaitem.shape.extruder.casing.tooltip=Форма экструдера для изготовления оболочек
-metaitem.shape.extruder.pipe.tiny.name=Форма экструдера (Трубка)
-metaitem.shape.extruder.pipe.tiny.tooltip=Форма экструдера для изготовления трубок
+metaitem.shape.extruder.casing.tooltip=Форма экструдера для изготовления корпусов
+metaitem.shape.extruder.pipe.tiny.name=Форма экструдера (Очень маленькая труба)
+metaitem.shape.extruder.pipe.tiny.tooltip=Форма экструдера для изготовления очень маленьких труб
 metaitem.shape.extruder.pipe.small.name=Форма экструдера (Малая труба)
 metaitem.shape.extruder.pipe.small.tooltip=Форма экструдера для изготовления небольших труб
 metaitem.shape.extruder.pipe.normal.name=Форма экструдера (Средняя труба)
@@ -234,15 +234,15 @@ metaitem.shape.extruder.file.tooltip=Форма экструдера для из
 metaitem.shape.extruder.saw.name=Форма экструдера (Пильный диск)
 metaitem.shape.extruder.saw.tooltip=Форма экструдера для изготовления пил
 metaitem.shape.extruder.gear.name=Форма экструдера (Шестерня)
-metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления зубчатых колес
+metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления шестерней
 metaitem.shape.extruder.bottle.name=Форма экструдера (Бутылка)
 metaitem.shape.extruder.bottle.tooltip=Форма экструдера для изготовления бутылок
 metaitem.shape.extruder.gear_small.name=Форма экструдера (маленькая шестеренка)
-metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестеренок
+metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестереней
 metaitem.shape.extruder.foil.name=Форма экструдера (Фольга)
 metaitem.shape.extruder.foil.tooltip=Форма экструдера для производства фольги из неметаллов
 metaitem.shape.extruder.rod_long.name=Форма экструдера (Длинный прут)
-metaitem.shape.extruder.rod_long.tooltip=Форма экструдера для производства длинных прутов
+metaitem.shape.extruder.rod_long.tooltip=Форма экструдера для производства прутьев
 metaitem.shape.extruder.rotor.name=Форма экструдера (Ротор)
 metaitem.shape.extruder.rotor.tooltip=Форма экструдера для производства роторов
 metaitem.spray.empty.name=Баллончик (Пустой)
@@ -386,7 +386,7 @@ metaitem.fluid.regulator.iv.name=Регулятор жидкости (§1IV§r)
 metaitem.fluid.regulator.luv.name=Регулятор жидкости (§dLuV§r)
 metaitem.fluid.regulator.zpm.name=Регулятор жидкости (§fZPM§r)
 metaitem.fluid.regulator.uv.name=Регулятор жидкости (§3UV§r)
-metaitem.fluid.regulator.tooltip=Ограничивает передачу §fЖидкостей§7 заданным количеством как §fУлучшение машины§7.
+metaitem.fluid.regulator.tooltip=Ограничивает передачу §fЖидкостей§7 заданным кол-вом как §fУлучшение машины§7.
 metaitem.conveyor.module.lv.name=Конвейерный модуль (§7LV§r)
 metaitem.conveyor.module.mv.name=Конвейерный модуль (§bMV§r)
 metaitem.conveyor.module.hv.name=Конвейерный модуль (§6HV§r)
@@ -427,7 +427,7 @@ metaitem.robot.arm.uev.name=Роботизированный манипулят
 metaitem.robot.arm.uiv.name=Роботизированный манипулятор (§2UIV§r)
 metaitem.robot.arm.uxv.name=Роботизированный манипулятор (§eUXV§r)
 metaitem.robot.arm.opv.name=Роботизированный манипулятор (§9OpV§r)
-metaitem.robot.arm.tooltip=Ограничивает передачу §fПредметов§7 заданным количеством как §fУлучшение механизма§7.
+metaitem.robot.arm.tooltip=Ограничивает передачу §fПредметов§7 заданным кол-вом как §fУлучшение механизма§7.
 metaitem.field.generator.lv.name=Генератор поля (§7LV§r)
 metaitem.field.generator.mv.name=Генератор поля (§bMV§r)
 metaitem.field.generator.hv.name=Генератор поля (§6HV§r)
@@ -511,7 +511,7 @@ metaitem.wafer.naquadah.name=Плаcтина легированная наква
 metaitem.wafer.naquadah.tooltip=Необработанная схема
 metaitem.wafer.neutronium.name=Пластина легированная нейтронием
 metaitem.wafer.neutronium.tooltip=Необработанная схема
-metaitem.board.coated.name=Прорезиненая подложка
+metaitem.board.coated.name=Прорезиненная подложка
 metaitem.board.coated.tooltip=Подложка с покрытием
 metaitem.board.phenolic.name=Профеноленая подложка
 metaitem.board.phenolic.tooltip=Хорошая подложка
@@ -521,7 +521,7 @@ metaitem.board.epoxy.name=Эпоксидная подложка
 metaitem.board.epoxy.tooltip=Продвинутая подложка
 metaitem.board.fiber_reinforced.name=Укрепленная эпоксидная подложка
 metaitem.board.fiber_reinforced.tooltip=Улучшенная подложка
-metaitem.board.multilayer.fiber_reinforced.name=Многослойная текстолитовая печатная плата
+metaitem.board.multilayer.fiber_reinforced.name=Многослойная текстолитовая подложка
 metaitem.board.multilayer.fiber_reinforced.tooltip=Превосходная подложка
 metaitem.board.wetware.name=Питательная подложка
 metaitem.board.wetware.tooltip=Подложка, которая хранит жизнь
@@ -572,9 +572,9 @@ metaitem.component.advanced_smd.resistor.name=Улучшенный SMD рези
 metaitem.component.advanced_smd.resistor.tooltip=Улучшенный электронный компонент
 metaitem.component.advanced_smd.inductor.name=Улучшенный SMD индуктор
 metaitem.component.advanced_smd.inductor.tooltip=Улучшенный электронный компонент
-metaitem.wafer.highly_advanced_system_on_chip.name=Пластина HASoC
-metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необработанная высоковольтажная микросхема
-metaitem.wafer.advanced_system_on_chip.name=Пластина ASoC
+metaitem.wafer.highly_advanced_system_on_chip.name=Пластина ОУСнК
+metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необработанная очень продвинутая микросхема
+metaitem.wafer.advanced_system_on_chip.name=Пластина УСнК
 metaitem.wafer.advanced_system_on_chip.tooltip=Необработанная продвинутая микросхема
 metaitem.wafer.integrated_logic_circuit.name=Пластина IC
 metaitem.wafer.integrated_logic_circuit.tooltip=Необработанная интегральная микросхема
@@ -592,17 +592,17 @@ metaitem.wafer.low_power_integrated_circuit.name=Пластина LPIC
 metaitem.wafer.low_power_integrated_circuit.tooltip=Необработанная низковольтажная микросхема
 metaitem.wafer.power_integrated_circuit.name=Пластина PIC
 metaitem.wafer.power_integrated_circuit.tooltip=Необработанная силовая микросхема
-metaitem.wafer.nano_central_processing_unit.name=Пластина Нано-процессора
+metaitem.wafer.nano_central_processing_unit.name=Пластина нано-процессора
 metaitem.wafer.nano_central_processing_unit.tooltip=Необработанная нано-микросхема
 metaitem.wafer.nor_memory_chip.name=Пластина NOR-памяти
 metaitem.wafer.nor_memory_chip.tooltip=Необработанная логическая схема
-metaitem.wafer.qbit_central_processing_unit.name=Пластина Qubit процессора
-metaitem.wafer.qbit_central_processing_unit.tooltip=Необработанная Qubit микросхема
+metaitem.wafer.qbit_central_processing_unit.name=Пластина кубитного процессора
+metaitem.wafer.qbit_central_processing_unit.tooltip=Необработанная кубитная микросхема
 metaitem.wafer.random_access_memory.name=Пластина RAM
 metaitem.wafer.random_access_memory.tooltip=Необработанная память
-metaitem.wafer.system_on_chip.name=Пластина SoC
+metaitem.wafer.system_on_chip.name=Пластина СнК
 metaitem.wafer.system_on_chip.tooltip=Необработанная обычная микросхема
-metaitem.wafer.simple_system_on_chip.name=Простая пластина SoC
+metaitem.wafer.simple_system_on_chip.name=Простая пластина СнК
 metaitem.wafer.simple_system_on_chip.tooltip=Необработанная простая микросхема
 metaitem.engraved.crystal_chip.name=Гравированный кристальный чип
 metaitem.engraved.crystal_chip.tooltip=Требуется для микросхем
@@ -613,12 +613,12 @@ metaitem.crystal.raw_chip.tooltip=Компонент необработанно
 metaitem.engraved.lapotron_chip.name=Гравированный лапотронный кристальный чип
 metaitem.crystal.central_processing_unit.name=Кристалл CPU
 metaitem.crystal.central_processing_unit.tooltip=Кристалл блока обработки
-metaitem.crystal.system_on_chip.name=Кристальный SoC
-metaitem.crystal.system_on_chip.tooltip=Кристаллическая система на чипе
-metaitem.plate.advanced_system_on_chip.name=ASoC
-metaitem.plate.advanced_system_on_chip.tooltip=Улучшенная система в чипе
-metaitem.plate.highly_advanced_system_on_chip.name=HASoC
-metaitem.plate.highly_advanced_system_on_chip.tooltip=Очень улучшенная система в чипе
+metaitem.crystal.system_on_chip.name=Кристальный СнК
+metaitem.crystal.system_on_chip.tooltip=Кристаллическая система на кристалле
+metaitem.plate.advanced_system_on_chip.name=УСнК
+metaitem.plate.advanced_system_on_chip.tooltip=Улучшенная система на кристалле
+metaitem.plate.highly_advanced_system_on_chip.name=ОУСнК
+metaitem.plate.highly_advanced_system_on_chip.tooltip=Очень улучшенная система на кристалле
 metaitem.plate.integrated_logic_circuit.name=Интегральная схема
 metaitem.plate.integrated_logic_circuit.tooltip=Интегральная логическая схема
 metaitem.plate.central_processing_unit.name=Центральный процессор
@@ -643,10 +643,10 @@ metaitem.plate.qbit_central_processing_unit.name=Кубитный процесс
 metaitem.plate.qbit_central_processing_unit.tooltip=Кубитный центральный процессор
 metaitem.plate.random_access_memory.name=ОЗУ
 metaitem.plate.random_access_memory.tooltip=Оперативная память
-metaitem.plate.system_on_chip.name=SoC
-metaitem.plate.system_on_chip.tooltip=Система в чипе
-metaitem.plate.simple_system_on_chip.name=Обычная SoC
-metaitem.plate.simple_system_on_chip.tooltip=Простая система на чипе
+metaitem.plate.system_on_chip.name=СнК
+metaitem.plate.system_on_chip.tooltip=Система на кристалле
+metaitem.plate.simple_system_on_chip.name=Обычная СнК
+metaitem.plate.simple_system_on_chip.tooltip=Простая система на кристалле
 
 
 # T1: Electronic
@@ -667,7 +667,7 @@ metaitem.circuit.advanced_integrated.tooltip=Меньше и мощнее/n§6HV
 metaitem.circuit.nand_chip.name=NAND чип
 metaitem.circuit.nand_chip.tooltip=Превосходная простая микросхема/n§6ULV уровень
 metaitem.circuit.microprocessor.name=Микропроцессор
-metaitem.circuit.microprocessor.tooltip=Улучшенная обычная микросхема/n§eLV уровень
+metaitem.circuit.microprocessor.tooltip=Совершенная обычная микросхема/n§eLV уровень
 
 # T3: Processor
 metaitem.circuit.processor.name=Интегральный микропроцессор
@@ -759,11 +759,11 @@ metaitem.cover.fluid.detector.tooltip=Выдает §fЗаполнение жи
 metaitem.cover.fluid.detector.advanced.name=Улучшенный детектор жидкости (Улучшение)
 metaitem.cover.fluid.detector.advanced.tooltip=Позволяет §fRS-триггеру§7 управлять §fСостоянием Хранилища жидкости§7 как редстоунов, в качестве §fКрышки§7.
 metaitem.cover.item.detector.name=Детектор предметов (Улучшение)
-metaitem.cover.item.detector.tooltip=Выдает §fКоличество предметов§7 Сигналом Красного камня как §fУлучшение механизма§7.
+metaitem.cover.item.detector.tooltip=Выдает §fКол-во предметов§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.item.detector.advanced.name=Улучшенный детектор предметов (Улучшение)
 metaitem.cover.item.detector.advanced.tooltip=Позволяет §fRS-триггеру§7 управлять §fСостоянием Хранилища предметов§7 как редстоунов, в качестве §fКрышки§7.
 metaitem.cover.energy.detector.name=Детектор энергии (Улучшение)
-metaitem.cover.energy.detector.tooltip=Выдает §fКоличество энергии§7 Сигналом Красного камня как §fУлучшение механизма§7.
+metaitem.cover.energy.detector.tooltip=Выдает §fКол-во энергии§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.energy.detector.advanced.name=Улучшенный детектор энергии (Улучшение)
 metaitem.cover.energy.detector.advanced.tooltip=Даёт §fRS-триггерный контроль за Уровнем энергии§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.fluid.voiding.name=Удаление жидкостей (Улучшение)
@@ -777,7 +777,7 @@ metaitem.cover.item.voiding.advanced.tooltip=Удаляет §fПредметы
 metaitem.cover.storage.name=Хранилище (Улучшение)
 metaitem.cover.storage.tooltip=Небольшое хранилище для хранения мелочей
 metaitem.cover.maintenance.detector.name=Детектор неисправностей (Улучшение)
-metaitem.cover.maintenance.detector.tooltip=Выдает §Количество Неисправностей§7 Сигналом Красного камня как §fУлучшение механизма§7.
+metaitem.cover.maintenance.detector.tooltip=Выдает §Кол-во Неисправностей§7 Сигналом Красного камня как §fУлучшение механизма§7.
 metaitem.cover.facade.name=Фасад (%s)
 metaitem.cover.facade.tooltip=Декоративный элемент.
 metaitem.cover.screen.name=Компьютерный монитор (Улучшение)
@@ -827,7 +827,7 @@ metaitem.plant_ball.name=Комок биомассы
 metaitem.tool_parts_box.name=Ящик для инструментов
 metaitem.tool_parts_box.tooltip=Для хранения инструментов/nЩелкните правой кнопкой, чтобы открыть
 metaitem.foam_sprayer.name=Пенный распылитель
-metaitem.foam_sprayer.tooltip=Распыляет строительную пену/nЩелкните правой кнопкой, чтобы запенить соединенные рамки./nИспользуйте металл для создания армированного бетона/nПена может быть цветной
+metaitem.foam_sprayer.tooltip=Распыляет строительную пену/nЩелкните правой кнопкой, чтобы запенить соединенные Каркасы./nИспользуйте металл для создания армированного бетона/nПена может быть цветной
 metaitem.energium_dust.name=Энергетическая пыль
 metaitem.compressed.clay.name=Сжатая глина
 metaitem.compressed.fireclay.name=Сжатая шамотная глина
@@ -937,7 +937,7 @@ item.gt.tool.harvest_level.3=§bАлмаз
 item.gt.tool.harvest_level.4=§dУльтимет
 item.gt.tool.harvest_level.5=§9Дураний
 item.gt.tool.harvest_level.6=§cНейтроний
-item.gt.tool.tooltip.repair_info=Удерживайте SHIFT для информации о Ремонте
+item.gt.tool.tooltip.repair_info=Зажмите SHIFT для Информации о Ремонте
 item.gt.tool.tooltip.repair_material=Чинится: §a%s
 item.gt.tool.aoe.rows=Рядов
 item.gt.tool.aoe.columns=Столбцов
@@ -1051,14 +1051,14 @@ metaitem.nan.certificate.tooltip=Вызов принят!
 metaitem.fertilizer.name=Удобрение
 metaitem.blacklight.name=Черный свет
 metaitem.blacklight.tooltip=Источник длинноволнового §dультрафиолетового§7 излучения
-gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить количество
+gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить кол-во
 gui.widget.recipeProgressWidget.default_tooltip=Показать рецепт
 gregtech.recipe_memory_widget.tooltip.2=§7Нажмите Shift, чтобы заблокировать/разблокировать этот рецепт
 gregtech.recipe_memory_widget.tooltip.1=§7Щелкните левой кнопкой мыши, чтобы автоматически добавить этот рецепт в сетку крафта
 cover.filter.blacklist.disabled=Белый список
 cover.filter.blacklist.enabled=Черный список
 cover.ore_dictionary_filter.title=Фильтр по словарю руд
-cover.ore_dictionary_filter.info=§bПринимает сложные выражения/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r для группировки/n§6*§r для подстановочного знака/n§6?§r для любого 1 символа/n§6()§r для пустого места (включая предметы из словаря руд)/n§6$c§r для начала выражения с учетов регистра/n§bПример:/n§6dust*Gold | (plate* & !*Double*)/nПодходит для всей золотой пыли всех размеров или всех пластин, но не для двойных пластин
+cover.ore_dictionary_filter.info=§bПринимает сложные выражения/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r для группировки/n§6*§r для подстановочного знака/n§6?§r для любого 1 символа/n§6()§r для пустого места (включая предметы из словаря руд)/n§bПример:/n§6dust*Gold | (plate* & !*Double*)/nПодходит для всей золотой пыли всех размеров или всех пластин, но не для двойных пластин
 cover.ore_dictionary_filter.test_slot.info=Вставьте элемент, чтобы проверить, соответствует ли он выражению фильтра
 cover.ore_dictionary_filter.test_slot.matches=§a* %s
 cover.ore_dictionary_filter.test_slot.matches_not=§c* %s
@@ -1070,7 +1070,7 @@ cover.ore_dictionary_filter.status.warn=§7%s предупреждение(я)
 cover.ore_dictionary_filter.status.no_issues=§aНет проблем
 cover.ore_dictionary_filter.status.explain=Объяснение фильтра руды:
 cover.fluid_filter.title=Жидкостный фильтр
-cover.fluid_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПравый клик увеличивает количество, левый уменьшает./nУдерживайте Shift, чтобы удвоить/уполовинить./nЩелкните средней кнопкой, чтобы очистить
+cover.fluid_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПравый клик увеличивает кол-во, левый уменьшает./nУдерживайте Shift, чтобы удвоить/уполовинить./nЩелкните средней кнопкой, чтобы очистить
 cover.fluid_filter.mode.filter_fill=Фильтрует при наполнении
 cover.fluid_filter.mode.filter_drain=Фильтрует при сливе
 cover.fluid_filter.mode.filter_both=Фильтрует при сливе и наполнении
@@ -1098,7 +1098,7 @@ cover.smart_item_filter.title=Умный предметный фильтр
 cover.smart_item_filter.filtering_mode.electrolyzer=Электролизер
 cover.smart_item_filter.filtering_mode.centrifuge=Центрифуга
 cover.smart_item_filter.filtering_mode.sifter=Просеиватель
-cover.smart_item_filter.filtering_mode.description=Выберите механизм для которой будут/не будут фильтроваться предметы для роботической руки.
+cover.smart_item_filter.filtering_mode.description=Выберите машину, которую этот Умный фильтр будет использовать для фильтрации./nОн автоматически отберет нужное кол-во предметов для роб. манипулятора.
 cover.conveyor.title=Настройки улучшения конвейера (%s)
 cover.conveyor.transfer_rate=§7предметов/с
 cover.conveyor.mode.export=Режим: Экспорт
@@ -1115,7 +1115,7 @@ cover.conveyor.item_filter.title=Фильтр предметов
 cover.conveyor.ore_dictionary.title=Название по словарю руд
 cover.conveyor.ore_dictionary.title2=(используйте * как подстановочный знак)
 cover.robotic_arm.title=Настройки роб. манипулятора (%s)
-cover.robotic_arm.transfer_mode.transfer_any=Перемещение любое количество
+cover.robotic_arm.transfer_mode.transfer_any=Перемещение любое кол-во
 cover.robotic_arm.transfer_mode.transfer_exact=Перемещать ровно
 cover.robotic_arm.transfer_mode.keep_exact=Поддерживать ровно
 cover.robotic_arm.transfer_mode.description=§eПеремещение любых предметов§r - в этом режиме улучшение будет передавать как можно больше предметов, соответствующих фильтру./n§eПодавать точно§r - в этом режиме улучшение будет поставлять предметы порциями, указанными в слотах фильтра предметов (или скоростью передачи для §bФильтра Словаря руды§r). Если количество предметов меньше размера порции, предметы не будут перемещены ./n§eСохранять точно§r - в этом режиме обложка сохранит указанное количество предметов в целевом инвентаре, предоставляя дополнительное количество предметов, если это необходимо./n§7Подсказка: щелкните Лкм или Пкм на слотах фильтра, чтобы изменить количество предметов,  используйте Shift, чтобы изменять количество быстрее.
@@ -1162,7 +1162,7 @@ cover.advanced_fluid_detector.label=Улучшенный детектор жид
 cover.advanced_fluid_detector.max=Макс. жидкости:
 cover.advanced_fluid_detector.min=Мин. жидкости:
 cover.advanced_item_detector.label=Улучшенный детектор предметов
-cover.advanced_item_detector.invert_tooltip=Переключите, чтобы инвертировать логику красного камня./nПо умолчанию красный камень перестает испускать сигнал, когда количество предметов меньше минимального, и начинает испускать сигнал, при превышении минимального количества предметов до установленного максимума
+cover.advanced_item_detector.invert_tooltip=Переключите, чтобы инвертировать логику красного камня./nПо умолчанию красный камень перестает испускать сигнал, когда кол-во предметов меньше мин., и начинает испускать сигнал, при превышении мин. кол-ва предметов до установленного макс
 cover.advanced_item_detector.max=Макс. предметов:
 cover.advanced_item_detector.min=Мин. предметов:
 cover.storage.title=Хранилище (Улучшение)
@@ -1203,8 +1203,8 @@ item.material.oreprefix.plateDouble=%s (Двойная пластина)
 item.material.oreprefix.plate=%s (Пластина)
 item.material.oreprefix.plank=Доска (%s)
 item.material.oreprefix.foil=%s (Фольга)
-item.material.oreprefix.stick=%s (Прут)
-item.material.oreprefix.stickLong=%s (Стержень)
+item.material.oreprefix.stick=%s (Стержень)
+item.material.oreprefix.stickLong=%s (Прут)
 item.material.oreprefix.round=%s (Шарик)
 item.material.oreprefix.bolt=%s (Болт)
 item.material.oreprefix.screw=%s (Винт)
@@ -1264,7 +1264,7 @@ item.material.oreprefix.polymer.plate=%s (Лист)
 item.material.oreprefix.polymer.foil=%s (Фольга)
 item.material.oreprefix.polymer.nugget=%s (Осколок)
 item.material.oreprefix.polymer.plateDense=%s (Плотный лист)
-item.material.oreprefix.polymer.plateDouble=%s (Плотный лист)
+item.material.oreprefix.polymer.plateDouble=%s (Двойной лист)
 item.material.oreprefix.polymer.dustTiny=%s (Крохотная кучка)
 item.material.oreprefix.polymer.dustSmall=%s (Маленькая кучка)
 item.material.oreprefix.polymer.dust=%s (Пыль)
@@ -1942,7 +1942,7 @@ item.gregtech.material.cassiterite_sand.dustImpure=Грязная кучка к
 item.gregtech.material.cassiterite_sand.dustPure=Очищеная кучка касситеритного песка
 item.gregtech.material.cassiterite_sand.dust=Касситеритовый песок
 item.gregtech.material.dark_ash.dustTiny=Крошечная кучка пепла
-item.gregtech.material.dark_ash.dustSmall=Маленькая кучка темного пепла
+item.gregtech.material.dark_ash.dustSmall=Маленькая кучка пепла
 item.gregtech.material.dark_ash.dust=Пепел
 item.gregtech.material.ice.dustTiny=Крошечная кучка колотого льда
 item.gregtech.material.ice.dustSmall=Маленькая кучка колотого льда
@@ -2006,9 +2006,9 @@ item.gregtech.material.bentonite.dustPure=Очищеный кучка бенто
 item.gregtech.material.bentonite.dustSmall=Маленькая кучка бентонита
 item.gregtech.material.bentonite.dustTiny=Крошечная кучка бентонита
 item.gregtech.material.bentonite.dust=Бентонит
-item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка странной земли
-item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка странной земли
-item.gregtech.material.fullers_earth.dust=Странная земля
+item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка смектической глины
+item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка cмектической глины
+item.gregtech.material.fullers_earth.dust=Смектическая глина
 item.gregtech.material.pitchblende.crushed=Измельчённый уранит
 item.gregtech.material.pitchblende.crushedCentrifuged=Центрифугированный уранит
 item.gregtech.material.pitchblende.crushedPurified=Очищеный уранит
@@ -2187,7 +2187,7 @@ behavior.tricorder.bedrock_fluid.amount=Жидкость в месторожде
 behavior.tricorder.bedrock_fluid.amount_unknown=Жидкость в месторождении: %s%%
 behavior.tricorder.bedrock_fluid.nothing=Жидкость в месторождении: §6Ничего§r
 behavior.tricorder.eut_per_sec=За последняя секунду прошло %s EU/t
-behavior.tricorder.amp_per_sec=За последняя секунду прошло %s A
+behavior.tricorder.amp_per_sec=За последнюю секунду прошло %s A
 behavior.tricorder.workable_consumption=Примерно использует: %s EU/t при %s A
 behavior.tricorder.workable_production=Примерно производит: %s EU/т при %s A
 behavior.tricorder.workable_progress=Прогресс: %s с / %s с
@@ -2239,7 +2239,7 @@ tile.casing.ev=Корпус машины (§5EV§r)
 tile.casing.iv=Корпус машины (§1IV§r)
 
 # Wire coil blocks
-tile.wire_coil.tooltip_extended_info=Зажмите SHIFT для просмотра Бонуса Катушек
+tile.wire_coil.tooltip_extended_info=Зажмите SHIFT для Информации о Бонуса Катушек
 tile.wire_coil.tooltip_heat=§cТеплоемкость: §f%,d K
 tile.wire_coil.tooltip_smelter=§8Мультиплавильня:
 tile.wire_coil.tooltip_parallel_smelter=§5Параллелей: §f%s
@@ -2365,10 +2365,10 @@ tile.machine_casing.overpowered_voltage.name=Корпус машины (OpV)
 tile.machine_casing.maximum_voltage.name=Корпус машины (MAX)
 
 # Steam casing blocks
-tile.steam_casing.bronze_hull.name=Бронзовый корпус
-tile.steam_casing.bronze_bricks_hull.name=Бронзовый кирпичный корпус
-tile.steam_casing.steel_hull.name=Стальной корпус
-tile.steam_casing.steel_bricks_hull.name=Кирпичный корпус из кованого железа
+tile.steam_casing.bronze_hull.name=Бронзовая оболочка
+tile.steam_casing.bronze_bricks_hull.name=Бронзовая кирпичная оболочка
+tile.steam_casing.steel_hull.name=Стальная оболочка
+tile.steam_casing.steel_bricks_hull.name=Кирпичная оболочка из кованого железа
 tile.steam_casing.bronze.tooltip=Для ваших первых паровых машин
 tile.steam_casing.steel.tooltip=Для улучшенных паровых машин
 tile.steam_casing.pump_deck.name=Насосная палуба
@@ -2929,7 +2929,7 @@ gregtech.machine.canner.uhv.name=Идеальный наполнитель
 gregtech.machine.canner.uhv.tooltip=Электроконсерватор
 gregtech.machine.canner.uev.name=Идеальный наполнитель II
 gregtech.machine.canner.uev.tooltip=Электроконсерватор
-gregtech.machine.canner.uiv.name=Идеальный наполнитель II
+gregtech.machine.canner.uiv.name=Идеальный наполнитель III
 gregtech.machine.canner.uiv.tooltip=Электроконсерватор
 gregtech.machine.canner.uxv.name=Идеальный наполнитель IV
 gregtech.machine.canner.uxv.tooltip=Электроконсерватор
@@ -3087,7 +3087,7 @@ gregtech.machine.distillery.zpm.name=Превосходный дистиллят
 gregtech.machine.distillery.uv.name=Безупречный дистиллятор
 gregtech.machine.distillery.uhv.name=Идеальный дистиллятор
 gregtech.machine.distillery.uev.name=Идеальный дистиллятор II
-gregtech.machine.distillery.uiv.name=Идеальный дистиллятор II
+gregtech.machine.distillery.uiv.name=Идеальный дистиллятор III
 gregtech.machine.distillery.uxv.name=Идеальный дистиллятор IV
 gregtech.machine.distillery.lv.tooltip=Извлечение наиболее важных частей жидкостей
 gregtech.machine.distillery.mv.tooltip=Извлечение наиболее важных частей жидкостей
@@ -3477,7 +3477,7 @@ gregtech.machine.polarizer.zpm.name=Превосходный поляризат
 gregtech.machine.polarizer.uv.name=Безупречный поляризатор
 gregtech.machine.polarizer.uhv.name=Идеальный поляризатор
 gregtech.machine.polarizer.uev.name=Идеальный поляризатор II
-gregtech.machine.polarizer.uiv.name=Идеальный поляризатор II
+gregtech.machine.polarizer.uiv.name=Идеальный поляризатор III
 gregtech.machine.polarizer.uxv.name=Идеальный поляризатор IV
 gregtech.machine.polarizer.lv.tooltip=Биполяризация ваших магнитов
 gregtech.machine.polarizer.mv.tooltip=Биполяризация ваших магнитов
@@ -3727,21 +3727,21 @@ gregtech.creative_tooltip.3=§7 чтобы использовать это
 
 # Machine hulls
 gregtech.machine.hull.tooltip=§7Вам просто нужно §5В§dо§4о§cб§eр§aа§bж§3е§7н§1и§5е§7 чтобы использовать это
-gregtech.machine.hull.ulv.name=Корпус машины (§8ULV§r)
-gregtech.machine.hull.lv.name=Корпус машины (§7LV§r)
-gregtech.machine.hull.mv.name=Корпус машины (§bMV§r)
-gregtech.machine.hull.hv.name=Корпус машины (§6HV§r)
-gregtech.machine.hull.ev.name=Корпус машины (§5EV§r)
-gregtech.machine.hull.iv.name=Корпус машины (§1IV§r)
-gregtech.machine.hull.luv.name=Корпус машины (§dLuV§r)
-gregtech.machine.hull.zpm.name=Корпус машины (§fZPM§r)
-gregtech.machine.hull.uv.name=Корпус машины (§3UV§r)
-gregtech.machine.hull.uhv.name=Корпус машины (§4UHV§r)
-gregtech.machine.hull.uev.name=Корпус машины (§aUEV§r)
-gregtech.machine.hull.uiv.name=Корпус машины (§2UIV§r)
-gregtech.machine.hull.uxv.name=Корпус машины (§eUXV§r)
-gregtech.machine.hull.opv.name=Корпус машины (§9OpV§r)
-gregtech.machine.hull.max.name=Корпус машины (§cMAX§r)
+gregtech.machine.hull.ulv.name=Оболочка машины (§8ULV§r)
+gregtech.machine.hull.lv.name=Оболочка машины (§7LV§r)
+gregtech.machine.hull.mv.name=Оболочка машины (§bMV§r)
+gregtech.machine.hull.hv.name=Оболочка машины (§6HV§r)
+gregtech.machine.hull.ev.name=Оболочка машины (§5EV§r)
+gregtech.machine.hull.iv.name=Оболочка машины (§1IV§r)
+gregtech.machine.hull.luv.name=Оболочка машины (§dLuV§r)
+gregtech.machine.hull.zpm.name=Оболочка машины (§fZPM§r)
+gregtech.machine.hull.uv.name=Оболочка машины (§3UV§r)
+gregtech.machine.hull.uhv.name=Оболочка машины (§4UHV§r)
+gregtech.machine.hull.uev.name=Оболочка машины (§aUEV§r)
+gregtech.machine.hull.uiv.name=Оболочка машины (§2UIV§r)
+gregtech.machine.hull.uxv.name=Оболочка машины (§eUXV§r)
+gregtech.machine.hull.opv.name=Оболочка машины (§9OpV§r)
+gregtech.machine.hull.max.name=Оболочка машины (§cMAX§r)
 
 # Battery buffers
 gregtech.machine.battery_buffer.ulv.4.name=Батарейный буфер (4 ячейки §8ULV§r)
@@ -3794,7 +3794,7 @@ gregtech.battery_buffer.average_input=Ввод в среднем: %s EU/t
 
 # Transformers
 gregtech.machine.transformer.description=Преобразует энергию между уровнями напряжения
-gregtech.machine.transformer.higher_amp.description=Преобразует энергию между уровнями напряжения, теперь с большим количеством ампер!
+gregtech.machine.transformer.higher_amp.description=Преобразует энергию между уровнями напряжения, теперь с большим кол-вом ампер!
 gregtech.machine.transformer.tooltip_tool_usage=По умолчанию §fПонижающий режим§7, используйте киянку чтобы инвертировать режим
 gregtech.machine.transformer.tooltip_transform_down=§aПонижающий режим: §f%dA %d EU (%s§f) -> %dA %d EU (%s§f)
 gregtech.machine.transformer.message_transform_down=Понижает напряжение, вход: %d EU %dA, выход: %d EU %dA
@@ -4268,8 +4268,8 @@ gregtech.advancement.extreme_voltage.50_nano_processor.name=Нано-проце
 gregtech.advancement.extreme_voltage.50_nano_processor.desc=Получите нано-процессор.
 gregtech.advancement.extreme_voltage.51_large_combustion_engine.name=Большой дизельный генератор
 gregtech.advancement.extreme_voltage.51_large_combustion_engine.desc=Соберите большой дизельный генератор, снабдите его смазкой и ускорьте кислородом.
-gregtech.advancement.extreme_voltage.52_soc_wafer.name=Пластина SoC
-gregtech.advancement.extreme_voltage.52_soc_wafer.desc=Сделайте Пластину SoC для более дешёвого производства микропроцессоров и интегральных микросхем.
+gregtech.advancement.extreme_voltage.52_soc_wafer.name=Пластина СНК
+gregtech.advancement.extreme_voltage.52_soc_wafer.desc=Сделайте Пластину СНК для более дешёвого производства микропроцессоров и интегральных микросхем.
 gregtech.advancement.root_iv.name=Безумный вольтаж
 gregtech.advancement.root_iv.desc=Охладите горячую вольфрамовую сталь.
 gregtech.advancement.insane_voltage.53_plutonium_239.name=Плутоний-239
@@ -4300,8 +4300,8 @@ gregtech.advancement.ludicrous_voltage.65_naquadah.name=Материал зве
 gregtech.advancement.ludicrous_voltage.65_naquadah.desc=Охладите горячий слиток наквады.
 gregtech.advancement.ludicrous_voltage.66_naquadah_coil.name=Улучшите ваши катушки до уровня VI
 gregtech.advancement.ludicrous_voltage.66_naquadah_coil.desc=Создайте катушку из наквады.
-gregtech.advancement.ludicrous_voltage.67_asoc_wafer.name=Пластина ASoC
-gregtech.advancement.ludicrous_voltage.67_asoc_wafer.desc=Сделайте Пластину SoC для более дешёвого производства нано-процессоров и квантовых процессоров.
+gregtech.advancement.ludicrous_voltage.67_asoc_wafer.name=Пластина УСНК
+gregtech.advancement.ludicrous_voltage.67_asoc_wafer.desc=Сделайте Пластину СНК для более дешёвого производства нано-процессоров и квантовых процессоров.
 gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.name=Большая плазменная турбина
 gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.desc=Создайте плазменную турбину, использующую плазму как топливо.
 gregtech.advancement.root_zpm.name=Модуль нулевой точки
@@ -4330,8 +4330,8 @@ gregtech.advancement.ultimate_voltage.76_neutronium.name=Как можно пл
 gregtech.advancement.ultimate_voltage.76_neutronium.desc=Получите нейтроний.
 gregtech.advancement.ultimate_voltage.77_ultimate_battery.name=И что теперь?
 gregtech.advancement.ultimate_voltage.77_ultimate_battery.desc=Создайте безупречную батарею.
-gregtech.advancement.ultimate_voltage.78_hasoc_wafer.name=Пластина HASoC
-gregtech.advancement.ultimate_voltage.78_hasoc_wafer.desc=Сделайте пластину HASoC для более дешёвого производства органических микросхем.
+gregtech.advancement.ultimate_voltage.78_hasoc_wafer.name=Пластина ОУСнК
+gregtech.advancement.ultimate_voltage.78_hasoc_wafer.desc=Сделайте пластину СУСНК для более дешёвого производства органических микросхем.
 gregtech.advancement.ultimate_voltage.79_tritanium_coil.name=Финальная катушка
 gregtech.advancement.ultimate_voltage.79_tritanium_coil.desc=Изготовьте нагревательную катушку из Тритания.
 
@@ -4436,14 +4436,14 @@ gregtech.machine.cleanroom.tooltip.1=Установите машины внут
 gregtech.machine.cleanroom.tooltip.2=Использует §f30 EU/t§7 когда загрязнена, §f4 EU/t§7 когда очищена.
 gregtech.machine.cleanroom.tooltip.3=Разгон увеличивает очистку за один цикл.
 gregtech.machine.cleanroom.tooltip.4=§bРазмер: от §f5x5x5 до 15x15x15
-gregtech.machine.cleanroom.tooltip.hold_ctrl=Зажмите CTRL для просмотра дополнительной информации о структуре
+gregtech.machine.cleanroom.tooltip.hold_ctrl=Зажмите CTRL для Дополнительной информации о структуре
 gregtech.machine.cleanroom.tooltip.5=Требует установку §fКорпуса фильтра §7в любом месте потолка кроме его граней.
 gregtech.machine.cleanroom.tooltip.6=Позволяет установить до §f4 дверей§7! Требует повторную очистку при открытой двери.
 gregtech.machine.cleanroom.tooltip.7=Генераторы, глушители, буры и примитивные машины слишком грязные для чистой комнаты!
-gregtech.machine.cleanroom.tooltip.8=Подавайте питание через §fКорпуса §7или §fДиоды §7в стенах.
+gregtech.machine.cleanroom.tooltip.8=Подавайте питание через §fОболочку §7или §fДиоды §7в стенах.
 gregtech.machine.cleanroom.tooltip.9=Отправляйте предметы и жидкости с помощью §fСквозных люков§7в стенах.
-gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fКорпуса§7 в стенах.
-gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fКорпуса§7 в стенах.
+gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fОболочку§7 в стенах.
+gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fОболочку§7 в стенах.
 gregtech.multiblock.cleanroom.dirty_state=Статус: §4ЗАГРЯЗНЕНА
 gregtech.multiblock.cleanroom.clean_state=Статус: §aЧИСТАЯ
 gregtech.machine.charcoal_pile.name=Воспламенитель угольной ямы
@@ -4468,10 +4468,10 @@ gregtech.machine.power_substation.tooltip5=Ограниченно §f%,d EU/t§7
 gregtech.multiblock.power_substation.description=Силовая Подстанция представляет собой многоблочную структуру, используемую для хранения огромного количества Энергии. Способен вместить до 18 слоев батарей. Также можно использовать пустые Накопители для заполнения пространства, так как слои должны быть полностью заполнены.
 gregtech.machine.active_transformer.name=Активный Трансформатор
 gregtech.machine.active_transformer.tooltip1=Трансформеры: Замаскированные лазеры
-gregtech.machine.active_transformer.tooltip2=Может комбинировать любое количество Энергетических §fВходных§7 разъемов в любое количество Энергетических §fВыходных§7 разъемов.
+gregtech.machine.active_transformer.tooltip2=Может комбинировать любое кол-во Энергетических §fВходных§7 разъемов в любое кол-во Энергетических §fВыходных§7 разъемов.
 gregtech.machine.active_transformer.tooltip3=Может передавать энергию на невероятное расстояние с помощью
 gregtech.machine.active_transformer.tooltip3.5=Лазеров§7.
-gregtech.multiblock.active_transformer.description=Активный Трансформатор представляет собой многоблочную структуру, которая может принимать любое количество или уровень энергетических входных разъемов преобразовывать их в любое количество или уровень энергетических выходных разъемов. Они могут быть соединены с Люком для Лазерного Источника и Люком для Лазерного Приемника, что позволяет передавать энергию на большие расстояния без каких-либо потерь. Лазеры должны располагаться по прямой, иначе они не будут посылать энергию.
+gregtech.multiblock.active_transformer.description=Активный Трансформатор представляет собой многоблочную структуру, которая может принимать любое кол-во или уровень энергетических входных разъемов преобразовывать их в любое кол-во или уровень энергетических выходных разъемов. Они могут быть соединены с Люком для Лазерного Источника и Люком для Лазерного Приемника, что позволяет передавать энергию на большие расстояния без каких-либо потерь. Лазеры должны располагаться по прямой, иначе они не будут посылать энергию.
 gregtech.machine.research_station.name=Станция исследований
 gregtech.machine.research_station.tooltip.1=Больше чем Многоблочный Сканнер
 gregtech.machine.research_station.tooltip.2=Используется для сканирования §fСфер данных§7 или §fМодулей данных§7.
@@ -4480,13 +4480,13 @@ gregtech.multiblock.research_station.description=Исследовательск
 gregtech.machine.network_switch.name=Коммутатор
 gregtech.machine.network_switch.tooltip.1=Ethernet-концентратор
 gregtech.machine.network_switch.tooltip.2=Используется для маршрутизации и распределения §fВычислений§7.
-gregtech.machine.network_switch.tooltip.3=Можно объединить любое количество §fПриемников§7 Вычислений в любое количество §fПередатчиков§7 Вычислений.
-gregtech.multiblock.network_switch.description=Коммутатор представляет собой многоблочную структуру, используемую для распределения вычислительных ресурсов из многих источников во многие пункты назначения. Он может принимать любое количество Люков Приема или Передачи вычислительных данных. Это необходимо для Исследовательских Данных, которые требуют гораздо больших Вычислений, поскольку исследовательская станция может принимать только один люк для приема данных вычислений. HPCA должен иметь Компонент Моста, чтобы сетевой коммутатор мог получить доступ к своим вычислениям.
+gregtech.machine.network_switch.tooltip.3=Можно объединить любое кол-во §fПриемников§7 Вычислений в любое кол-во §fПередатчиков§7 Вычислений.
+gregtech.multiblock.network_switch.description=Коммутатор представляет собой многоблочную структуру, используемую для распределения вычислительных ресурсов из многих источников во многие пункты назначения. Он может принимать любое кол-во Люков Приема или Передачи вычислительных данных. Это необходимо для Исследовательских Данных, которые требуют гораздо больших Вычислений, поскольку исследовательская станция может принимать только один люк для приема данных вычислений. HPCA должен иметь Компонент Моста, чтобы сетевой коммутатор мог получить доступ к своим вычислениям.
 gregtech.machine.high_performance_computing_array.name=Высокопроизводительный вычислительный массив
 gregtech.machine.high_performance_computing_array.tooltip.1=Просто самый обычный Суперкомпьютер
 gregtech.machine.high_performance_computing_array.tooltip.2=Используется для генерации §fВычислений§7 (и тепла).
 gregtech.machine.high_performance_computing_array.tooltip.3=Требуются компоненты HPCA для создания §fCWU/t§7 (Вычислительные Рабочие Единицы).
-gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное количество вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения.
+gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное ко-во вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения.
 gregtech.machine.central_monitor.name=Центральный монитор
 gregtech.multiblock.central_monitor.low_power=Недостаточно энергии
 gregtech.multiblock.central_monitor.height=Высота экрана:
@@ -4578,7 +4578,6 @@ gregtech.machine.item_bus.export.uv.name=Предметный выходной 
 gregtech.machine.item_bus.export.uhv.name=Предметный выходной люк (§4UHV§r)
 gregtech.bus.collapse_true=Люк будет совмещать Предметы
 gregtech.bus.collapse_false=Люк не будет совмещать Предметы
-gregtech.bus.collapse.error=Люк должен быть сперва добавлен в многоблочную структуру
 gregtech.machine.fluid_hatch.import.tooltip=Для подачи жидкости в многоблочную структуру
 gregtech.machine.fluid_hatch.import.ulv.name=Жидкостный входной люк (§8ULV§r)
 gregtech.machine.fluid_hatch.import.lv.name=Жидкостный входной люк (§7LV§r)
@@ -4699,7 +4698,7 @@ gregtech.maintenance.configurable_time=Время: %fx
 gregtech.maintenance.configurable_time.unchanged_description=Проблемы с обслуживанием будут возникать с обычной частотой. Измените конфигурацию для обновления.
 gregtech.maintenance.configurable_time.changed_description=Проблемы с обслуживанием будут возникать в %f раз чаще.
 gregtech.maintenance.configurable.tooltip_basic=Ускоряет время работы машины за счет более частых проблем с обслуживанием
-gregtech.maintenance.configurable.tooltip_more_info=Зажмите SHIFT для особого взаимодействия
+gregtech.maintenance.configurable.tooltip_more_info=Зажмите SHIFT для Особого взаимодействия
 gregtech.maintenance.configurable.tooltip_pss_header=§8Силовая Подстанция:
 gregtech.maintenance.configurable.tooltip_pss_info=§fУменьшает пассивную утечку энергии
 gregtech.machine.muffler_hatch.tooltip1=Восстанавливает отходы от машин
@@ -4783,7 +4782,7 @@ gregtech.universal.tooltip.fluid_stored=§dОбъем жидкости: §f%s, %
 gregtech.universal.tooltip.fluid_transfer_rate=§bСкорость передачи: §f%,d Л/т
 gregtech.universal.tooltip.parallel=§dПаралеллей: §f%d
 gregtech.universal.tooltip.working_area=§bРабочая область: §f%,dx%,d
-gregtech.universal.tooltip.working_area_max=§bМаксимальная рабочая область: §f%,dx%,d
+gregtech.universal.tooltip.working_area_max=§bМакс. рабочая область: §f%,dx%,d
 gregtech.universal.tooltip.working_area_chunks_max=§bMax Working Area: §f%,dx%,d Chunks
 gregtech.universal.tooltip.uses_per_tick=Потребляет §f%,d EU/т §7когда работает
 gregtech.universal.tooltip.uses_per_tick_steam=Потребляет §f%,d Л/т §7 Пара когда работает
@@ -4815,7 +4814,7 @@ gregtech.recipe.computation_per_tick=Мин. Вычисления: %,d CWU/t
 gregtech.fluid.click_to_fill=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7резервуар.
 gregtech.fluid.click_to_empty=§7Нажмите с хралищем для жидкости, чтобы §cопустошить §7резервуар.
 gregtech.fluid.click_combined=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7или §cопустошить §7резервуар.
-gregtech.tool_action.show_tooltips=Зажмите SHIFT для просмотра информации Инструмента
+gregtech.tool_action.show_tooltips=Зажмите SHIFT для Информации о Инструменте
 gregtech.tool_action.screwdriver.auto_output=§8Используйте отвертку, чтобы переключить Авто-Вывод
 gregtech.tool_action.screwdriver.toggle_mode_covers=§8Используйте отвертку, чтобы переключить Режим или настроить улучшения
 gregtech.tool_action.screwdriver.access_covers=§8Используйте отвертку, чтобы настроить улучшения
@@ -4834,8 +4833,8 @@ gregtech.tool_action.tape=§8Используйте Клейкую Ленту д
 gregtech.fluid.generic=%s
 gregtech.fluid.plasma=Плазма (%s)
 gregtech.fluid.empty=Пустой
-gregtech.fluid.amount=§7%,d/%,d
-gregtech.fluid.temperature=§7Температура: %dK
+gregtech.fluid.amount=§9Количество: %,d/%,d Л
+gregtech.fluid.temperature=§cТемпература: %dK
 gregtech.fluid.temperature.cryogenic=§bКриогенный! Соблюдайте осторожность!
 gregtech.fluid.state_gas=§7Состояние: Газообразный
 gregtech.fluid.state_liquid=§7Состояние: Жидкость
@@ -4843,7 +4842,7 @@ gregtech.fluid.state_plasma=§7Состояние: Плазма
 gregtech.fluid.type_acid.tooltip=§6Кислота! Соблюдайте осторожность!
 gregtech.gui.fuel_amount=Кол. топлива:
 gregtech.gui.fluid_amount=Кол. жидкости:
-gregtech.gui.amount_raw=Количество:
+gregtech.gui.amount_raw=Кол-во:
 gregtech.gui.toggle_view.disabled=Переключить вид (Жидкости)
 gregtech.gui.toggle_view.enabled=Переключить вид (Предметы)
 gregtech.gui.overclock.enabled=Ускорение включено./nНажмите, чтобы отключить
@@ -4856,7 +4855,7 @@ gregtech.gui.fluid_auto_output.tooltip.disabled=Авто. вывод жидко
 gregtech.gui.item_auto_output.tooltip.enabled=Авто. вывод предметов включен
 gregtech.gui.item_auto_output.tooltip.disabled=Авто. вывод предметов отключен
 gregtech.gui.charger_slot.tooltip=§fСлот двухстороннего питания§r/n§7Может потреблять энергию от %s §7аккумуляторов либо-же отдавать
-gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r/n§aУстановить Значение: §f%d§7/n/n§7ЛКМ/ПКМ/Прокрутка для переключения по листу/n§7Shift-ПКМ для очистка
+gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r\n§aУстановить Значение: §f%d§7\n\n§7ЛКМ/ПКМ/Прокрутка для переключения по листу\n§7Shift-ЛКМ чтобы выбрать селектор\n§7Shift-ПКМ для очистка
 gregtech.gui.fluid_lock.tooltip.enabled=Блокировка жидкости включена
 gregtech.gui.fluid_lock.tooltip.disabled=Блокировка жидкости выключена
 gregtech.gui.fluid_voiding.tooltip.enabled=Удаление избытков жидкости Включен
@@ -4871,7 +4870,7 @@ gregtech.gui.me_network.offline=Статус Сети: §2Не в Сети§r
 gregtech.gui.waiting_list=Очередь на отправку:
 gregtech.gui.config_slot=§fНастройка§r
 gregtech.gui.config_slot.set=§7Нажмите для §bвыбора/настройкиt§7 слота.§r
-gregtech.gui.config_slot.scroll=§7Колесо мыши §aизменяет§7 количество.§r
+gregtech.gui.config_slot.scroll=§7Колесо мыши §aизменяет§7 кол-во.§r
 gregtech.gui.config_slot.remove=§7Правая кнопка для §4очистки§7 слота настройки.§r
 ore.spawnlocation.name=Информация о появлении руды
 gregtech.jei.ore.surface_rock_1=Поверхностные залежи с этим материалом обозначают места появления жил.
@@ -4904,8 +4903,8 @@ fluid.spawnlocation.name=Информация о жидкостном место
 
 
 gregtech.jei.materials.average_mass=Средняя масса: %,d
-gregtech.jei.materials.average_neutrons=Среднее количество нейтронов: %,d
-gregtech.jei.materials.average_protons=Среднее количество протонов: %,d
+gregtech.jei.materials.average_neutrons=Ср. кол-во нейтронов: %,d
+gregtech.jei.materials.average_protons=Ср. кол-во протонов: %,d
 gregtech.item_filter.empty_item=Пусто (нет предмета)
 gregtech.item_filter.footer=§eНажмите с предметом, чтобы переопределить
 gregtech.cable.voltage=§aВольтаж: §f%,d §f(%s§f)
@@ -4929,12 +4928,12 @@ gregtech.multiblock.not_enough_energy_output=§eСовет:§f Энергети
 gregtech.multiblock.progress=Прогресс: %s%%
 gregtech.multiblock.invalid_structure=Неверная структура.
 gregtech.multiblock.invalid_structure.tooltip=Этот блок является контроллером многоблочной структуры. для получения справки по созданию см. шаблон структуры в JEI.
-gregtech.multiblock.validation_failed=Неверное количество входов/выходов.
+gregtech.multiblock.validation_failed=Неверное кол-во входов/выходов.
 gregtech.multiblock.max_energy_per_tick=Макс. EU/т: §a%s (%s§r)
 gregtech.multiblock.generation_eu=Генерирует:§a%s EU/t
 gregtech.multiblock.universal.no_problems=Механизм работает исправно!
 gregtech.multiblock.universal.has_problems=Механизм неисправен!
-gregtech.multiblock.universal.has_problems_header=Исправьте следующие проблемы в люке обслуживания:
+gregtech.multiblock.universal.has_problems_header=Исправьте следующие проблемы в Люке обслуживания:
 gregtech.multiblock.universal.problem.wrench=%s§7Труба расшатана. (§aКлюч§7)
 gregtech.multiblock.universal.problem.screwdriver=%s§7Винты не закручены. (§aОтвертка§7)
 gregtech.multiblock.universal.problem.soft_mallet=%s§7Что-то заклинило. (§aКиянка§7)
@@ -4946,7 +4945,7 @@ gregtech.multiblock.universal.distinct_enabled=Раздельные люки: §
 gregtech.multiblock.universal.distinct_disabled=Раздельные люки: §aВsключено§r/nКаждый входной люк будет рассматриваться как комбинированный ввод для поиска рецепта.
 gregtech.multiblock.universal.distinct_not_supported=Эту структура не поддерживает Раздельные Люки
 gregtech.multiblock.universal.no_flex_button=Эта структура не имеет дополнительных функций с этой кнопкой.
-gregtech.multiblock.parallel=Параллельное выполнение до %d рецептов
+gregtech.multiblock.parallel=Макс. Параллелей: %s
 gregtech.multiblock.multiple_recipemaps.header=Режим машины:
 gregtech.multiblock.multiple_recipemaps.tooltip=Нажмите отвёрткой по контроллеру, чтобы изменить режим машины.
 gregtech.multiblock.multiple_recipemaps_recipes.tooltip=Режим машин: §e%s§r
@@ -4976,9 +4975,9 @@ gregtech.multiblock.blast_furnace.max_temperature=Максимальная те
 gregtech.multiblock.multi_furnace.heating_coil_discount=EU усиление нагревательной катушки: %sx
 gregtech.multiblock.distillation_tower.distilling_fluid=Дистилляция %s
 gregtech.multiblock.large_combustion_engine.no_lubricant=Нет Смазки.
-gregtech.multiblock.large_combustion_engine.lubricant_amount=Количество смазки: %smB
-gregtech.multiblock.large_combustion_engine.oxygen_amount=Количество кислорода: %smB
-gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Количество жидкого кислорода: %smB
+gregtech.multiblock.large_combustion_engine.lubricant_amount=Кол-во смазки: %smB
+gregtech.multiblock.large_combustion_engine.oxygen_amount=Кол-во кислорода: %smB
+gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Кол-во жид. кислорода: %smB
 gregtech.multiblock.large_combustion_engine.oxygen_boosted=§bКислород добавлен.
 gregtech.multiblock.large_combustion_engine.liquid_oxygen_boosted=§bЖидкий кислород добавлен.
 gregtech.multiblock.large_combustion_engine.supply_oxygen_to_boost=Принимает кислород для ускорения.
@@ -4986,11 +4985,11 @@ gregtech.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost=При
 gregtech.multiblock.large_combustion_engine.obstructed=Что-то мешает воздухозаборнику двигателя.
 gregtech.multiblock.turbine.fuel_amount=Топлива: %smB (%s)
 gregtech.multiblock.turbine.rotor_speed=Скорость: %s/%s об/мин
-gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s%%
+gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s
 gregtech.multiblock.turbine.rotor_durability_low=Прочность ротора низкая!
 gregtech.multiblock.turbine.no_rotor=Нет Ротора в Держателе ротора.
 gregtech.multiblock.turbine.fuel_needed=Потребляет %s за %s тиков
-gregtech.multiblock.turbine.efficiency=Эффективность турбины: %s%%
+gregtech.multiblock.turbine.efficiency=Эффективность турбины: %s
 gregtech.multiblock.turbine.energy_per_tick=Выход: %s/%s EU/t
 gregtech.multiblock.turbine.obstructed=Поверхность турбины заблокирована
 gregtech.multiblock.turbine.efficiency_tooltip=Каждый держатель ротора выше %s§7 добавляет §f10%% эффективности§7.
@@ -5076,7 +5075,7 @@ gregtech.command.copy.click_to_copy=Нажмите для копирования
 gregtech.command.copy.copied_start=Скопировано [
 gregtech.command.copy.copied_end=] в буфер обмена
 gregtech.chat.cape=§5Поздравляю: вы только что разблокировали новый плащ! Откройте в терминале Переключатель плащей для подробной информации.§r
-gregtech.universal.clear_nbt_recipe.tooltip=§cЭто уничтожить весь контент!
+gregtech.universal.clear_nbt_recipe.tooltip=§cЭто уничтожит весь контент!
 gregtech.cover.detector_base.message_inverted_state=Статус детектора: Инвертированный
 gregtech.cover.detector_base.message_normal_state=Статус детектора: Обычный
 gregtech.creative.chest.item=Предмет
@@ -5906,3 +5905,10 @@ for.bees.species.fluorine=Фторовая
 
 # Bee Descriptions (many more to do)
 for.bees.description.clay=Органическая пчела, известная своей трудолюбивостью и усердием. Ходят слухи, что их можно найти грязь в нужном биоме.|Пчеловодство 101
+gregtech.gui.item_auto_collapse.tooltip.disabled=Авто-совмещение предметов выключено
+gregtech.gui.item_auto_collapse.tooltip.enabled=Авто-совмещение предметов включено
+gregtech.gui.configurator_slot.unavailable.tooltip=Слот Интегральной схемы недоступен
+cover.ore_dictionary_filter.button.case_sensitive.enabled=С учетом регистра
+cover.ore_dictionary_filter.button.match_all.disabled=Любая из записей из Словаря руд
+cover.ore_dictionary_filter.button.match_all.enabled=Все записи из Словаря руд
+cover.ore_dictionary_filter.button.case_sensitive.disabled=Без учета регистра

From 57b40a7c203b0539a9db13f0681a52fd366a2e03 Mon Sep 17 00:00:00 2001
From: ALongStringOfNumbers
 <31759736+ALongStringOfNumbers@users.noreply.github.com>
Date: Wed, 3 Jan 2024 09:55:46 -0700
Subject: [PATCH 043/168] Improve Lighter Opening (#2323)

---
 .../items/behaviors/LighterBehaviour.java     | 23 +++++++++++++++----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java
index 4e1f14cfa61..6dd8d6742c7 100644
--- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java
+++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java
@@ -24,7 +24,13 @@
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.*;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.SoundCategory;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.world.World;
 import net.minecraftforge.fluids.FluidStack;
@@ -89,20 +95,27 @@ public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity en
     }
 
     @Override
-    public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world, BlockPos pos,
-                                           EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) {
+    public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
         ItemStack stack = player.getHeldItem(hand);
         NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(stack);
 
         if (canOpen && player.isSneaking()) {
             compound.setBoolean(LIGHTER_OPEN, !compound.getBoolean(LIGHTER_OPEN));
             stack.setTagCompound(compound);
-            return EnumActionResult.PASS;
         }
+        return ActionResult.newResult(EnumActionResult.PASS, stack);
+    }
+
+    @Override
+    public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world, BlockPos pos,
+                                           EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) {
+        ItemStack stack = player.getHeldItem(hand);
+        NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(stack);
 
         if (!player.canPlayerEdit(pos, side, player.getHeldItem(hand))) return EnumActionResult.FAIL;
         // If this item does not have opening mechanics, or if it does and is currently open
-        if ((!canOpen || compound.getBoolean(LIGHTER_OPEN)) && consumeFuel(player, stack)) {
+        // If the item has opening mechanics, and the player is sneaking, close the item instead
+        if ((!canOpen || (compound.getBoolean(LIGHTER_OPEN)) && !player.isSneaking()) && consumeFuel(player, stack)) {
             player.getEntityWorld().playSound(null, player.getPosition(), SoundEvents.ITEM_FLINTANDSTEEL_USE,
                     SoundCategory.PLAYERS, 1.0F, GTValues.RNG.nextFloat() * 0.4F + 0.8F);
             IBlockState blockState = world.getBlockState(pos);

From 8070829343ab437f720129ccf98000b155222bb8 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:14:05 -0500
Subject: [PATCH 044/168] Fix some JEI plugin issues (#2337)

---
 src/main/java/gregtech/api/recipes/Recipe.java     | 11 +++++++++--
 .../integration/jei/JustEnoughItemsModule.java     | 14 +++++++-------
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java
index b291f994301..f52c3adc10e 100644
--- a/src/main/java/gregtech/api/recipes/Recipe.java
+++ b/src/main/java/gregtech/api/recipes/Recipe.java
@@ -29,7 +29,13 @@
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Class that represent machine recipe.
@@ -673,8 +679,9 @@ public boolean hasValidInputsForDisplay() {
                         .anyMatch(s -> !s.isEmpty())) {
                     return true;
                 }
+            } else if (Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty())) {
+                return true;
             }
-            return Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty());
         }
         for (GTRecipeInput fluidInput : fluidInputs) {
             FluidStack fluidIngredient = fluidInput.getInputFluidStack();
diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java
index b6c1d9519bf..5c89ad0bb61 100644
--- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java
+++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java
@@ -57,10 +57,10 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -197,7 +197,7 @@ public void register(IModRegistry registry) {
         registry.addRecipeCatalyst(MetaTileEntities.LARGE_TITANIUM_BOILER.getStackForm(), semiFluidMapId);
         registry.addRecipeCatalyst(MetaTileEntities.LARGE_TUNGSTENSTEEL_BOILER.getStackForm(), semiFluidMapId);
 
-        List oreByproductList = new CopyOnWriteArrayList<>();
+        List oreByproductList = new ArrayList<>();
         for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) {
             if (material.hasProperty(PropertyKey.ORE)) {
                 oreByproductList.add(new OreByProduct(material));
@@ -205,7 +205,7 @@ public void register(IModRegistry registry) {
         }
         String oreByProductId = GTValues.MODID + ":" + "ore_by_product";
         registry.addRecipes(oreByproductList, oreByProductId);
-        MetaTileEntity[][] machineLists = new MetaTileEntity[][] {
+        MetaTileEntity[][] machineLists = {
                 MetaTileEntities.MACERATOR,
                 MetaTileEntities.ORE_WASHER,
                 MetaTileEntities.CENTRIFUGE,
@@ -220,7 +220,7 @@ public void register(IModRegistry registry) {
         }
 
         // Material Tree
-        List materialTreeList = new CopyOnWriteArrayList<>();
+        List materialTreeList = new ArrayList<>();
         for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) {
             if (material.hasProperty(PropertyKey.DUST)) {
                 materialTreeList.add(new MaterialTree(material));
@@ -230,7 +230,7 @@ public void register(IModRegistry registry) {
 
         // Ore Veins
         List oreVeins = WorldGenRegistry.getOreDeposits();
-        List oreInfoList = new CopyOnWriteArrayList<>();
+        List oreInfoList = new ArrayList<>();
         for (OreDepositDefinition vein : oreVeins) {
             oreInfoList.add(new GTOreInfo(vein));
         }
@@ -244,7 +244,7 @@ public void register(IModRegistry registry) {
 
         // Fluid Veins
         List fluidVeins = WorldGenRegistry.getBedrockVeinDeposits();
-        List fluidVeinInfos = new CopyOnWriteArrayList<>();
+        List fluidVeinInfos = new ArrayList<>();
         for (BedrockFluidDepositDefinition fluidVein : fluidVeins) {
             fluidVeinInfos.add(new GTFluidVeinInfo(fluidVein));
         }
@@ -290,7 +290,7 @@ private void setupInputHandler() {
 
             showsRecipeFocuses.add(new MultiblockInfoRecipeFocusShower());
 
-        } catch (Exception e) {
+        } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | SecurityException e) {
             getLogger().error("Could not reflect JEI Internal inputHandler", e);
         }
     }

From c93d91c257a035208cab40f824c4d85e511d697b Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sat, 6 Jan 2024 14:20:12 -0600
Subject: [PATCH 045/168] Fix treated wood stick saw recipe (#2339)

---
 src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java
index fb06348d385..c790b6c809d 100644
--- a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java
+++ b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java
@@ -482,7 +482,7 @@ private static void registerGTWoodRecipes() {
                 'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK));
         if (ConfigHolder.recipes.nerfWoodCrafting) {
             ModHandler.addShapedRecipe("treated_wood_stick_saw", OreDictUnifier.get(OrePrefix.stick, TreatedWood, 4),
-                    "s", "L",
+                    "s", "L", "L",
                     'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK));
         }
     }

From c7bf6d3566302d8cd23fec0b9e9df6b2cc0bf23b Mon Sep 17 00:00:00 2001
From: iouter <62897714+iouter@users.noreply.github.com>
Date: Mon, 8 Jan 2024 11:19:55 +0800
Subject: [PATCH 046/168] update zh_cn.lang (#2334)

---
 .../resources/assets/gregtech/lang/zh_cn.lang | 41 +++++++++++--------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang
index f410418bbce..adbc85e0853 100644
--- a/src/main/resources/assets/gregtech/lang/zh_cn.lang
+++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang
@@ -531,7 +531,7 @@ metaitem.tool.datamodule.name=数据模块
 metaitem.tool.datamodule.tooltip=超复杂数据存储/n§c只能用数据库读取
 metaitem.circuit.integrated.name=编程电路
 metaitem.circuit.integrated.tooltip=右击以打开配置界面/n/n手持并潜行右击带有编程电路槽位的机器可应用相应配置。/n
-metaitem.circuit.integrated.gui=编程电路配置
+metaitem.circuit.integrated.gui=电路配置
 metaitem.circuit.integrated.jei_description=JEI将仅显示匹配当前编程电路配置的配方。\n\n在编程电路配置界面中调整配置以查看对应配方。
 
 item.glass.lens=玻璃透镜(白色)
@@ -1175,7 +1175,7 @@ cover.filter.blacklist.disabled=白名单
 cover.filter.blacklist.enabled=黑名单
 
 cover.ore_dictionary_filter.title=矿物词典过滤
-cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §6$c§r 可严格区分大小写/n§b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉
+cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉
 cover.ore_dictionary_filter.test_slot.info=放入一件物品以测试是否匹配过滤表达式
 cover.ore_dictionary_filter.test_slot.matches=§a* %s
 cover.ore_dictionary_filter.test_slot.matches_not=§c* %s
@@ -1186,6 +1186,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s个错误、%s个警告
 cover.ore_dictionary_filter.status.warn=§7%s个警告
 cover.ore_dictionary_filter.status.no_issues=§a无问题
 cover.ore_dictionary_filter.status.explain=矿物过滤说明:
+cover.ore_dictionary_filter.button.case_sensitive.disabled=匹配大小写
+cover.ore_dictionary_filter.button.case_sensitive.enabled=忽略大小写
+cover.ore_dictionary_filter.button.match_all.disabled=匹配物品的任一矿词条目
+cover.ore_dictionary_filter.button.match_all.enabled=匹配物品的所有矿词条目
 
 cover.ore_dictionary_filter.preview.next=...接着是
 cover.ore_dictionary_filter.preview.match='%s'
@@ -1300,11 +1304,6 @@ cover.fluid_regulator.transfer_mode.description=§e任意传输§r - 在此模
 cover.fluid_regulator.supply_exact=精确补给:%s
 cover.fluid_regulator.keep_exact=保持补给:%s
 
-cover.machine_controller.title=机器控制设定
-cover.machine_controller.normal=普通
-cover.machine_controller.inverted=反相
-cover.machine_controller.inverted.description=§e普通§r - 该模式下的覆盖板需要比设定强度小的红石信号来触发/n§e反相§r - 该模式下的覆盖板需要比设定强度大的红石信号来触发
-cover.machine_controller.redstone=最小红石信号强度:%,d
 cover.machine_controller.mode.machine=控制目标:机器
 cover.machine_controller.mode.cover_up=控制目标:覆盖板(顶面)
 cover.machine_controller.mode.cover_down=控制目标:覆盖板(底面)
@@ -1312,6 +1311,12 @@ cover.machine_controller.mode.cover_south=控制目标:覆盖板(南面)
 cover.machine_controller.mode.cover_north=控制目标:覆盖板(北面)
 cover.machine_controller.mode.cover_east=控制目标:覆盖板(东面)
 cover.machine_controller.mode.cover_west=控制目标:覆盖板(西面)
+cover.machine_controller.this_cover=§c此覆盖板
+cover.machine_controller.cover_not_controllable=§c不可控制的覆盖板
+cover.machine_controller.machine_not_controllable=§c不可控制的机器
+cover.machine_controller.control=控制:
+cover.machine_controller.enable_with_redstone=接收红石信号时开启
+cover.machine_controller.disable_with_redstone=接收红石信号时关闭
 
 cover.ender_fluid_link.title=末影流体连接
 cover.ender_fluid_link.iomode.enabled=已启用I/O
@@ -1356,9 +1361,9 @@ item.material.oreprefix.oreBasalt=玄武岩%s矿石
 item.material.oreprefix.oreSand=沙子%s矿石
 item.material.oreprefix.oreRedSand=红沙%s矿石
 item.material.oreprefix.oreNetherrack=地狱岩%s矿石
-item.material.oreprefix.oreNether=下界%s矿石
+item.material.oreprefix.oreNether=地狱岩%s矿石
 item.material.oreprefix.oreEndstone=末地石%s矿石
-item.material.oreprefix.oreEnd=末地%s矿石
+item.material.oreprefix.oreEnd=末地石%s矿石
 item.material.oreprefix.ore=%s矿石
 item.material.oreprefix.oreGranite=花岗岩%s矿石
 item.material.oreprefix.oreDiorite=闪长岩%s矿石
@@ -4151,7 +4156,7 @@ gregtech.machine.transformer.adjustable.opv.name=过载压高能变压器(§9O
 gregtech.machine.diode.message=电流吞吐上限:%s
 gregtech.machine.diode.tooltip_tool_usage=手持软锤右击以调节电流。
 gregtech.machine.diode.tooltip_general=使能量作单向传输并限制电流
-gregtech.machine.diode.tooltip_starts_at=默认为§f1A§7,使用软锤来轮换电流设定
+gregtech.machine.diode.tooltip_starts_at=默认允许§f1A§r电流通行,使用软锤切换。
 
 gregtech.machine.diode.ulv.name=超低压二极管(§8ULV§r)
 gregtech.machine.diode.lv.name=低压二极管(§7LV§r)
@@ -4405,7 +4410,7 @@ gregtech.machine.world_accelerator.zpm.name=精英世界加速器 III
 gregtech.machine.world_accelerator.zpm.tooltip=“时间之§m瓶§r”§7方块
 gregtech.machine.world_accelerator.uv.name=终极世界加速器
 gregtech.machine.world_accelerator.uv.tooltip=时间扭曲者
-gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§7或§f随机刻§7模式中切换。
+gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§r或§f随机刻§7模式中切换。
 gregtech.machine.world_accelerator.power_usage=§7在随机刻模式下最多使用§f%dA,§7在方块实体模式下最多使用§f%dA 。
 gregtech.machine.world_accelerator.acceleration=§d加速倍率: §f%dx
 gregtech.machine.world_accelerator.working_area=§b作用范围:
@@ -4714,7 +4719,7 @@ gregtech.machine.large_chemical_reactor.name=大型化学反应釜
 gregtech.machine.large_combustion_engine.name=大型内燃引擎
 gregtech.machine.extreme_combustion_engine.name=极限内燃引擎
 gregtech.machine.large_combustion_engine.tooltip.boost_regular=提供§f20 L/s§7的氧气,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。
-gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80 L/s§7的液氧,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。
+gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80L/s§7的液态氧,并消耗§f双倍§7燃料以产生高达§f%s§7EU/t的功率。
 
 gregtech.machine.large_turbine.steam.name=大型蒸汽涡轮
 gregtech.machine.large_turbine.gas.name=大型燃气涡轮
@@ -4745,7 +4750,7 @@ gregtech.machine.large_miner.ev.name=基础采矿场
 gregtech.machine.large_miner.iv.name=进阶采矿场
 gregtech.machine.large_miner.luv.name=进阶采矿场 II
 gregtech.machine.miner.multi.modes=具有精准采集模式与区块对齐模式。
-gregtech.machine.miner.multi.production=粉碎矿石的产出量为§f研磨机§7的§f3倍§7。
+gregtech.machine.miner.multi.production=产出§f研磨机§7§f3x§7倍的粉碎矿石。
 gregtech.machine.miner.fluid_usage=每tick消耗§f%,d L§7的§f%s§7,超频时翻倍。
 gregtech.machine.miner.multi.description=一台工作范围极广的多方块采矿机,能够提供巨量矿石。
 gregtech.machine.miner.multi.needsfluid=钻井液不足!
@@ -4938,7 +4943,6 @@ gregtech.machine.item_bus.export.uhv.name=§4UHV§r输出总线
 
 gregtech.bus.collapse_true=已启用物品堆叠自动合并
 gregtech.bus.collapse_false=已禁用物品堆叠自动合并
-gregtech.bus.collapse.error=总线位于已成型的多方块结构后方可进行该操作
 
 gregtech.machine.fluid_hatch.import.tooltip=为多方块结构输入流体
 
@@ -5275,7 +5279,7 @@ gregtech.universal.tooltip.item_stored=§d内含物品:§f%2$,d + %3$,d 个%1$
 gregtech.universal.tooltip.item_transfer_rate=§b传输速率:§f%,d件物品/s
 gregtech.universal.tooltip.item_transfer_rate_stacks=§b传输速率:§f%,d组物品/s
 gregtech.universal.tooltip.fluid_storage_capacity=§9流体容量:§f%,d L
-gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:共§f%d§7个流体槽,每个§f%dL§7
+gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§r共§f%d§7个流体槽,每个§f%dL§7
 gregtech.universal.tooltip.fluid_stored=§d内含流体:§f%2$,d L %1$s
 gregtech.universal.tooltip.fluid_transfer_rate=§b传输速率:§f%,d L/t
 gregtech.universal.tooltip.parallel=§d最大并行:§f%d
@@ -5371,9 +5375,12 @@ gregtech.gui.fluid_auto_output.tooltip.enabled=流体自动输出已启用
 gregtech.gui.fluid_auto_output.tooltip.disabled=流体自动输出已禁用
 gregtech.gui.item_auto_output.tooltip.enabled=物品自动输出已启用
 gregtech.gui.item_auto_output.tooltip.disabled=物品自动输出已禁用
+gregtech.gui.item_auto_collapse.tooltip.enabled=物品堆叠自动合并已启用
+gregtech.gui.item_auto_collapse.tooltip.disabled=物品堆叠自动合并已禁用
 gregtech.gui.charger_slot.tooltip=§f充电槽§r/n§7从%s电池中取电§7/n§7也可为%s工具或电池充电
-gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r/n§a配置值:§f%d§7/n/n§7左击/右击/滚轮可浏览循环列表/n§7Shift+右键单击以清除
+gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r\n§a配置值:§f%d§7\n\n§7左击/右击/滚轮可循环浏览列表\n§7Shift+左键单击以打开选择GUI\n§7Shift+右键单击以清除
 gregtech.gui.configurator_slot.no_value=空
+gregtech.gui.configurator_slot.unavailable.tooltip=编程电路槽位无法使用
 gregtech.gui.fluid_lock.tooltip.enabled=流体锁定已启用
 gregtech.gui.fluid_lock.tooltip.disabled=流体锁定已禁用
 gregtech.gui.fluid_voiding.tooltip.enabled=过量流体销毁已启用
@@ -5560,7 +5567,7 @@ gregtech.multiblock.pattern.error.batteries=§c必须至少有一个不是空电
 gregtech.multiblock.pattern.error.filters=§c必须使用同种过滤器§r
 gregtech.multiblock.pattern.clear_amount_1=§6前方必须有1x1x1大小的空间§r
 gregtech.multiblock.pattern.clear_amount_3=§6前方必须有3x3x1大小的空间§r
-gregtech.multiblock.pattern.single=§6仅可使用该种方块§r
+gregtech.multiblock.pattern.single=§6仅可使用该种方块类型§r
 gregtech.multiblock.pattern.location_end=§c最末端§r
 gregtech.multiblock.pattern.replaceable_air=可为空气
 

From 60b6ffe932d85e2e8c9d0aa11cb30455f4791788 Mon Sep 17 00:00:00 2001
From: Serenibyss <10861407+serenibyss@users.noreply.github.com>
Date: Sun, 7 Jan 2024 21:33:34 -0600
Subject: [PATCH 047/168] Update build script version to 1704659416 (#2341)

Co-authored-by: DStrand1 
Co-authored-by: alongstringofnumbers 
---
 build.gradle      | 67 ++++++++++++++++++++++++++++++++++++++---------
 gradle.properties |  3 +++
 settings.gradle   |  4 +--
 3 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/build.gradle b/build.gradle
index 913152a71c5..ebae36cf19e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-//version: 1702805890
+//version: 1704659416
 /*
  * DO NOT CHANGE THIS FILE!
  * Also, you may replace this file at any time if there is an update available.
@@ -62,6 +62,7 @@ propertyDefaultIfUnset("generateGradleTokenClass", "")
 propertyDefaultIfUnset("gradleTokenModId", "")
 propertyDefaultIfUnset("gradleTokenModName", "")
 propertyDefaultIfUnset("gradleTokenVersion", "")
+propertyDefaultIfUnset("useSrcApiPath", false)
 propertyDefaultIfUnset("includeWellKnownRepositories", true)
 propertyDefaultIfUnset("includeCommonDevEnvMods", true)
 propertyDefaultIfUnset("noPublishedSources", false)
@@ -105,9 +106,16 @@ if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists(
 }
 
 if (apiPackage) {
-    targetPackageJava = javaSourceDir + modGroupPath + '/' + apiPackagePath
-    targetPackageScala = scalaSourceDir + modGroupPath + '/' + apiPackagePath
-    targetPackageKotlin = kotlinSourceDir + modGroupPath + '/' + apiPackagePath
+    final String endApiPath = modGroupPath + '/' + apiPackagePath
+    if (useSrcApiPath) {
+        targetPackageJava = 'src/api/java/' + endApiPath
+        targetPackageScala = 'src/api/scala/' + endApiPath
+        targetPackageKotlin = 'src/api/kotlin/' + endApiPath
+    } else {
+        targetPackageJava = javaSourceDir + endApiPath
+        targetPackageScala = scalaSourceDir + endApiPath
+        targetPackageKotlin = kotlinSourceDir + endApiPath
+    }
     if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) {
         throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}")
     }
@@ -436,8 +444,7 @@ repositories {
         }
         maven {
             name 'GTNH Maven'
-            url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public'
-            allowInsecureProtocol = true
+            url 'https://nexus.gtnewhorizons.com/repository/public/'
         }
     }
     if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
@@ -675,6 +682,19 @@ jar {
             it.isDirectory() ? it : zipTree(it)
         }
     }
+
+    if (useSrcApiPath && apiPackage) {
+        from sourceSets.api.output
+        dependsOn apiClasses
+
+        include "${modGroupPath}/**"
+        include "assets/**"
+        include "mcmod.info"
+        include "pack.mcmeta"
+        if (accessTransformersFile) {
+            include "META-INF/${accessTransformersFile}"
+        }
+    }
 }
 
 // Configure default run tasks
@@ -691,12 +711,21 @@ if (separateRunDirectories.toBoolean()) {
 // Create API library jar
 tasks.register('apiJar', Jar) {
     archiveClassifier.set 'api'
-    from(sourceSets.main.java) {
-        include "${modGroupPath}/${apiPackagePath}/**"
-    }
+    if (useSrcApiPath) {
+        from(sourceSets.api.java) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
+        from(sourceSets.api.output) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
+    } else {
+        from(sourceSets.main.java) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
 
-    from(sourceSets.main.output) {
-        include "${modGroupPath}/${apiPackagePath}/**"
+        from(sourceSets.main.output) {
+            include "${modGroupPath}/${apiPackagePath}/**"
+        }
     }
 }
 
@@ -906,6 +935,12 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
                     }
                     String[] parts = dep.split(':')
                     String type = parts[0], slug = parts[1]
+                    def types = [
+                            'req'   : 'requiredDependency', 'required': 'requiredDependency',
+                            'opt'   : 'optionalDependency', 'optional': 'optionalDependency',
+                            'embed' : 'embeddedLibrary',    'embedded': 'embeddedLibrary',
+                            'incomp': 'incompatible',       'fail'    : 'incompatible']
+                    if (types.containsKey(type)) type = types[type]
                     if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) {
                         throw new Exception('Invalid Curseforge dependency type: ' + type)
                     }
@@ -948,7 +983,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
             }
             String[] parts = dep.split(':')
             String[] qual = parts[0].split('-')
-            addModrinthDep(qual[0], qual[1], parts[1])
+            addModrinthDep(qual[0], qual.length > 1 ? qual[1] : 'project', parts[1])
         }
     }
     tasks.modrinth.dependsOn(build)
@@ -957,9 +992,17 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
 
 def addModrinthDep(String scope, String type, String name) {
     com.modrinth.minotaur.dependencies.Dependency dep
+    def types = [
+            'req'   : 'required',
+            'opt'   : 'optional',
+            'embed' : 'embedded',
+            'incomp': 'incompatible', 'fail': 'incompatible']
+    if (types.containsKey(scope)) scope = types[scope]
     if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) {
         throw new Exception('Invalid modrinth dependency scope: ' + scope)
     }
+    types = ['proj': 'project', '': 'project', 'p': 'project', 'ver': 'version', 'v': 'version']
+    if (types.containsKey(type)) type = types[type]
     switch (type) {
         case 'project':
             dep = new ModDependency(name, scope)
diff --git a/gradle.properties b/gradle.properties
index 36eb31a2b21..7b97b1fe4f9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -42,6 +42,8 @@ gradleTokenVersion = VERSION
 # leave this property empty.
 # Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
 apiPackage =
+# If you want to keep your API code in src/api instead of src/main
+useSrcApiPath=false
 
 # Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/
 # There can be multiple files in a comma-separated list.
@@ -90,6 +92,7 @@ relocateShadowedDependencies = true
 # Separate run directories into "run/client" for runClient task, and "run/server" for runServer task.
 # Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/"
 separateRunDirectories = false
+
 # The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables.
 # Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse.
 versionDisplayFormat=$MOD_NAME: $VERSION
diff --git a/settings.gradle b/settings.gradle
index b6371aad5ab..771def37e1f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,9 +3,7 @@ pluginManagement {
         maven {
             // RetroFuturaGradle
             name 'GTNH Maven'
-            //noinspection HttpUrlsUsage
-            url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
-            allowInsecureProtocol = true
+            url 'https://nexus.gtnewhorizons.com/repository/public/'
             //noinspection GroovyAssignabilityCheck
             mavenContent {
                 includeGroup 'com.gtnewhorizons'

From 8c48186d5a1e8063bfc3ebe6eb7c16f31107d666 Mon Sep 17 00:00:00 2001
From: TechLord22 <37029404+TechLord22@users.noreply.github.com>
Date: Wed, 10 Jan 2024 09:18:26 -0500
Subject: [PATCH 048/168] prevent potential ThreadLocal memory leaks (#2320)

---
 .../gregtech/api/block/machines/BlockMachine.java | 15 ++++++++++++---
 .../gregtech/api/pipenet/block/BlockPipe.java     |  9 +++++++--
 .../gregtech/api/unification/ore/OrePrefix.java   | 14 +++++++++++---
 src/main/java/gregtech/asm/hooks/CTMHooks.java    |  2 +-
 .../renderer/handler/MetaTileEntityRenderer.java  |  2 +-
 .../client/renderer/pipe/PipeRenderer.java        |  2 +-
 6 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java
index f9a77ccbe07..d2deda21283 100644
--- a/src/main/java/gregtech/api/block/machines/BlockMachine.java
+++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java
@@ -40,7 +40,11 @@
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.*;
+import net.minecraft.util.BlockRenderLayer;
+import net.minecraft.util.EnumBlockRenderType;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
 import net.minecraft.util.math.AxisAlignedBB;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.RayTraceResult;
@@ -63,7 +67,12 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
 
 import static gregtech.api.util.GTUtility.getMetaTileEntity;
 
@@ -423,7 +432,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @
                              @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) {
         tileEntities.set(te == null ? tileEntities.get() : ((IGregTechTileEntity) te).getMetaTileEntity());
         super.harvestBlock(worldIn, player, pos, state, te, stack);
-        tileEntities.set(null);
+        tileEntities.remove();
     }
 
     @Nullable
diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java
index 5468aae38dd..667b67fcf52 100644
--- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java
+++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java
@@ -34,7 +34,12 @@
 import net.minecraft.item.EnumDyeColor;
 import net.minecraft.item.ItemStack;
 import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.*;
+import net.minecraft.util.BlockRenderLayer;
+import net.minecraft.util.EnumActionResult;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.EnumHand;
+import net.minecraft.util.NonNullList;
+import net.minecraft.util.SoundCategory;
 import net.minecraft.util.math.AxisAlignedBB;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.math.RayTraceResult;
@@ -485,7 +490,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @
                              @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) {
         tileEntities.set(te == null ? tileEntities.get() : (IPipeTile) te);
         super.harvestBlock(worldIn, player, pos, state, te, stack);
-        tileEntities.set(null);
+        tileEntities.remove();
     }
 
     @Override
diff --git a/src/main/java/gregtech/api/unification/ore/OrePrefix.java b/src/main/java/gregtech/api/unification/ore/OrePrefix.java
index 30239988324..0a159028f1d 100644
--- a/src/main/java/gregtech/api/unification/ore/OrePrefix.java
+++ b/src/main/java/gregtech/api/unification/ore/OrePrefix.java
@@ -23,7 +23,15 @@
 import stanhebben.zenscript.annotations.ZenClass;
 import stanhebben.zenscript.annotations.ZenMethod;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -631,11 +639,11 @@ private void runGeneratedMaterialHandlers() {
             for (IOreRegistrationHandler registrationHandler : oreProcessingHandlers) {
                 registrationHandler.processMaterial(this, registeredMaterial);
             }
-            currentMaterial.set(null);
+            currentMaterial.remove();
         }
         // clear generated materials for next pass
         generatedMaterials.clear();
-        currentProcessingPrefix.set(null);
+        currentProcessingPrefix.remove();
     }
 
     public void setAlternativeOreName(String name) {
diff --git a/src/main/java/gregtech/asm/hooks/CTMHooks.java b/src/main/java/gregtech/asm/hooks/CTMHooks.java
index 33ddc0d7754..eaf4f7ad51c 100644
--- a/src/main/java/gregtech/asm/hooks/CTMHooks.java
+++ b/src/main/java/gregtech/asm/hooks/CTMHooks.java
@@ -43,7 +43,7 @@ public static List getQuadsWithOptiFine(List ret, BlockRen
                 ForgeHooksClient.setRenderLayer(BloomEffectUtil.getBloomLayer());
                 result.addAll(bakedModel.getQuads(state, side, rand));
                 ForgeHooksClient.setRenderLayer(layer);
-                CTMHooks.ENABLE.set(null);
+                CTMHooks.ENABLE.remove();
                 return result;
             }
         }
diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java
index 5aa513fea8c..9436d30dc8d 100644
--- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java
+++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java
@@ -115,7 +115,7 @@ public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state,
 
         metaTileEntity.renderCovers(renderState, translation.copy(), renderLayer);
 
-        Textures.RENDER_STATE.set(null);
+        Textures.RENDER_STATE.remove();
         return true;
     }
 
diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java
index 632bdad8f2b..d16ca9ace07 100644
--- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java
+++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java
@@ -218,7 +218,7 @@ public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state,
             CoverHolder coverHolder = pipeTile.getCoverableImplementation();
             coverHolder.renderCovers(renderState, new Matrix4().translate(pos.getX(), pos.getY(), pos.getZ()),
                     renderLayer);
-            Textures.RENDER_STATE.set(null);
+            Textures.RENDER_STATE.remove();
         }
         return true;
     }

From 6e1a1678c808d6d3cb4bdc3f01136576790b0ec3 Mon Sep 17 00:00:00 2001
From: Tictim 
Date: Fri, 12 Jan 2024 08:03:59 +0900
Subject: [PATCH 049/168] Make translation key of MetaItems modifiable (#2259)

Co-authored-by: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com>
---
 .../gregtech/api/items/metaitem/MetaItem.java | 64 +++++++++++++------
 1 file changed, 46 insertions(+), 18 deletions(-)

diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java
index ba1f713f010..c0dac9c52fd 100644
--- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java
+++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java
@@ -72,21 +72,27 @@
 
 import java.time.Duration;
 import java.time.Instant;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 
 /**
- * MetaItem is item that can have up to Short.MAX_VALUE items inside one id.
- * These items even can be edible, have custom behaviours, be electric or act like fluid containers!
- * They can also have different burn time, plus be handheld, oredicted or invisible!
- * They also can be reactor components.
+ * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. These items even can be edible, have custom
+ * behaviours, be electric or act like fluid containers! They can also have different burn time, plus be handheld,
+ * oredicted or invisible! They also can be reactor components.
  * 

* You can also extend this class and occupy some of it's MetaData, and just pass an meta offset in constructor, and * everything will work properly. *

* Items are added in MetaItem via {@link #addItem(int, String)}. You will get {@link MetaValueItem} instance, which you * can configure in builder-alike pattern: - * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } - * This will add single-use (not rechargeable) LV battery with initial capacity 10000 EU + * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } This will add single-use (not + * rechargeable) LV battery with initial capacity 10000 EU */ @Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item @@ -110,8 +116,9 @@ public static List> getMetaItems() { private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GregTechAPI.TAB_GREGTECH }; private final Set additionalCreativeTabs = new ObjectArraySet<>(); + private String translationKey = "metaitem"; + public MetaItem(short metaItemOffset) { - setTranslationKey("meta_item"); setHasSubtypes(true); this.metaItemOffset = metaItemOffset; META_ITEMS.add(this); @@ -354,6 +361,7 @@ public void onPlayerStoppedUsing(@NotNull ItemStack stack, @NotNull World world, } } + @NotNull @Override public ItemStack onItemUseFinish(@NotNull ItemStack stack, @NotNull World world, @NotNull EntityLivingBase player) { if (player instanceof EntityPlayer) { @@ -527,10 +535,28 @@ public boolean shouldCauseReequipAnimation(@NotNull ItemStack oldStack, @NotNull return !ItemStack.areItemStacksEqual(oldStack, newStack); } + @NotNull @Override - public String getTranslationKey(ItemStack stack) { - T metaItem = getItem(stack); - return metaItem == null ? getTranslationKey() : getTranslationKey() + "." + metaItem.unlocalizedName; + public MetaItem setTranslationKey(@NotNull String key) { + this.translationKey = Objects.requireNonNull(key, "key == null"); + return this; + } + + @NotNull + @Override + public String getTranslationKey() { + return getTranslationKey((T) null); + } + + @NotNull + @Override + public String getTranslationKey(@NotNull ItemStack stack) { + return getTranslationKey(getItem(stack)); + } + + @NotNull + protected String getTranslationKey(@Nullable T metaValueItem) { + return metaValueItem == null ? this.translationKey : this.translationKey + "." + metaValueItem.unlocalizedName; } @NotNull @@ -541,7 +567,7 @@ public String getItemStackDisplayName(ItemStack stack) { if (item == null) { return "invalid item"; } - String unlocalizedName = String.format("metaitem.%s.name", item.unlocalizedName); + String unlocalizedName = getTranslationKey(item) + ".name"; if (item.getNameProvider() != null) { return item.getNameProvider().getItemStackDisplayName(stack, unlocalizedName); } @@ -564,7 +590,7 @@ public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn @NotNull ITooltipFlag tooltipFlag) { T item = getItem(itemStack); if (item == null) return; - String unlocalizedTooltip = "metaitem." + item.unlocalizedName + ".tooltip"; + String unlocalizedTooltip = getTranslationKey(item) + ".tooltip"; if (I18n.hasKey(unlocalizedTooltip)) { Collections.addAll(lines, LocalizationUtils.formatLines(unlocalizedTooltip)); } @@ -660,25 +686,27 @@ public ItemStack getContainerItem(@NotNull ItemStack itemStack) { @NotNull @Override - public CreativeTabs[] getCreativeTabs() { + public CreativeTabs @NotNull [] getCreativeTabs() { if (additionalCreativeTabs.isEmpty()) return defaultCreativeTabs; // short circuit Set tabs = new ObjectArraySet<>(additionalCreativeTabs); tabs.addAll(Arrays.asList(defaultCreativeTabs)); return tabs.toArray(new CreativeTabs[0]); } + @NotNull @Override - public MetaItem setCreativeTab(CreativeTabs tab) { + public MetaItem setCreativeTab(@NotNull CreativeTabs tab) { this.defaultCreativeTabs = new CreativeTabs[] { tab }; return this; } - public MetaItem setCreativeTabs(CreativeTabs... tabs) { + @NotNull + public MetaItem setCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { this.defaultCreativeTabs = tabs; return this; } - public void addAdditionalCreativeTabs(CreativeTabs... tabs) { + public void addAdditionalCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { for (CreativeTabs tab : tabs) { if (!ArrayUtils.contains(defaultCreativeTabs, tab) && tab != CreativeTabs.SEARCH) { additionalCreativeTabs.add(tab); @@ -687,7 +715,7 @@ public void addAdditionalCreativeTabs(CreativeTabs... tabs) { } @Override - protected boolean isInCreativeTab(CreativeTabs tab) { + protected boolean isInCreativeTab(@NotNull CreativeTabs tab) { return tab == CreativeTabs.SEARCH || ArrayUtils.contains(defaultCreativeTabs, tab) || additionalCreativeTabs.contains(tab); From fcee78aea0eb7c3f97371d7397b0003aec6fadf3 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sat, 13 Jan 2024 22:39:15 -0600 Subject: [PATCH 050/168] Update build script version to 1705076830 (#2344) Co-authored-by: DStrand1 --- build.gradle | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ebae36cf19e..f4c0964bd89 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1704659416 +//version: 1705076830 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -24,7 +24,7 @@ plugins { id 'eclipse' id 'maven-publish' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.25' + id 'com.gtnewhorizons.retrofuturagradle' version '1.3.28' id 'net.darkhax.curseforgegradle' version '1.1.17' apply false id 'com.modrinth.minotaur' version '2.8.6' apply false id 'com.diffplug.spotless' version '6.13.0' apply false @@ -541,6 +541,12 @@ pluginManager.withPlugin('org.jetbrains.kotlin.kapt') { } } +configurations.configureEach { + resolutionStrategy.dependencySubstitution { + substitute module('org.scala-lang:scala-library:2.11.1') using module('org.scala-lang:scala-library:2.11.5') because('To allow mixing with Java 8 targets') + } +} + if (getFile('dependencies.gradle').exists()) { apply from: 'dependencies.gradle' } else if (getFile('dependencies.gradle.kts').exists()) { From 6d327ff69a21fd60bbd540c55f19f3f6f6e7df54 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sat, 13 Jan 2024 22:52:49 -0600 Subject: [PATCH 051/168] Overload AbstractRecipeLogic functions (#2311) Co-authored-by: alongstringofnumbers --- .../capability/impl/AbstractRecipeLogic.java | 63 ++++++++++++++++--- .../LargeTurbineWorkableHandler.java | 2 +- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index cc2ce878aee..e00cdc21235 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -1,7 +1,11 @@ package gregtech.api.capability.impl; import gregtech.api.GTValues; -import gregtech.api.capability.*; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IMultiblockController; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.IWorkable; import gregtech.api.metatileentity.MTETrait; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.multiblock.CleanroomType; @@ -432,34 +436,53 @@ protected boolean checkCleanroomRequirement(@NotNull Recipe recipe) { *

    *
  1. The recipe is run in parallel if possible.
  2. *
  3. The potentially parallel recipe is then checked to exist.
  4. - *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
  7. If it exists, it checks if the recipe is runnable with the inputs provided.
  8. *
* If the above conditions are met, the recipe is engaged to be run * - * @param recipe the recipe to prepare + * @param recipe the recipe to prepare + * @param inputInventory the inventory to draw items from + * @param inputFluidInventory the fluid tanks to draw fluid from * @return true if the recipe was successfully prepared, else false */ - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe, IItemHandlerModifiable inputInventory, + IMultipleTankHandler inputFluidInventory) { recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); // Pass in the trimmed recipe to the parallel logic recipe = findParallelRecipe( recipe, - getInputInventory(), - getInputTank(), + inputInventory, + inputFluidInventory, getOutputInventory(), getOutputTank(), getMaxParallelVoltage(), getParallelLimit()); - if (recipe != null && setupAndConsumeRecipeInputs(recipe, getInputInventory())) { + if (recipe != null && setupAndConsumeRecipeInputs(recipe, inputInventory, inputFluidInventory)) { setupRecipe(recipe); return true; } return false; } + /** + * Prepares the recipe to be run. + *
    + *
  1. The recipe is run in parallel if possible.
  2. + *
  3. The potentially parallel recipe is then checked to exist.
  4. + *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
+ * If the above conditions are met, the recipe is engaged to be run + * + * @param recipe the recipe to prepare + * @return true if the recipe was successfully prepared from the default inventory, else false + */ + public boolean prepareRecipe(Recipe recipe) { + return prepareRecipe(recipe, getInputInventory(), getInputTank()); + } + /** * DO NOT use the parallelLimit field directly, EVER * @@ -549,11 +572,14 @@ protected static boolean areItemStacksEqual(@NotNull ItemStack stackA, @NotNull * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine * @param importInventory - The inventory that the recipe should be consumed from. * Used mainly for Distinct bus implementation for multiblocks to specify - * a specific bus + * a specific bus, or for addons to use external inventories. + * @param importFluids - The tanks that the recipe should be consumed from + * Used currently in addons to use external tanks. * @return - true if the recipe is successful, false if the recipe is not successful */ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory) { + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { this.overclockResults = calculateOverclock(recipe); modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); @@ -563,7 +589,6 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, } IItemHandlerModifiable exportInventory = getOutputInventory(); - IMultipleTankHandler importFluids = getInputTank(); IMultipleTankHandler exportFluids = getOutputTank(); // We have already trimmed outputs and chanced outputs at this time @@ -589,6 +614,24 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, return false; } + /** + * Determines if the provided recipe is possible to run from the provided inventory, or if there is anything + * preventing + * the Recipe from being completed. + *

+ * Will consume the inputs of the Recipe if it is possible to run. + * + * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine + * @param importInventory - The inventory that the recipe should be consumed from. + * Used mainly for Distinct bus implementation for multiblocks to specify + * a specific bus + * @return - true if the recipe is successful, false if the recipe is not successful + */ + protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory) { + return setupAndConsumeRecipeInputs(recipe, importInventory, this.getInputTank()); + } + /** * @param resultOverclock the overclock data to use. Format: {@code [EUt, duration]}. * @return true if there is enough energy to continue recipe progress diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java index db414ae4da7..f9f393216e6 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java @@ -131,7 +131,7 @@ protected boolean checkPreviousRecipe() { } @Override - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe) { IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder(); if (rotorHolder == null || !rotorHolder.hasRotor()) return false; From 55090d7c4bd44a6e7858086b50d85f45507a1354 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sat, 13 Jan 2024 23:01:55 -0600 Subject: [PATCH 052/168] Fix erroring material handlers when liquids don't exist (#2343) --- .../material/properties/FluidProperty.java | 34 +++++++++++++++++++ .../handlers/MaterialRecipeHandler.java | 13 +++---- .../recipe/handlers/PartsRecipeHandler.java | 13 +++---- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java index 48f92084252..80c971fb4f1 100644 --- a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java @@ -2,6 +2,10 @@ import gregtech.api.fluids.store.FluidStorage; import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,6 +14,7 @@ public class FluidProperty implements IMaterialProperty { private final FluidStorage storage = new FluidStorage(); private @Nullable FluidStorageKey primaryKey = null; + private @Nullable Fluid solidifyingFluid = null; public FluidProperty() {} @@ -33,4 +38,33 @@ public void setPrimaryKey(@Nullable FluidStorageKey primaryKey) { @Override public void verifyProperty(MaterialProperties properties) {} + + /** + * @return the Fluid which solidifies into the material. + */ + + public Fluid solidifiesFrom() { + if (this.solidifyingFluid == null) { + return getStorage().get(FluidStorageKeys.LIQUID); + } + return solidifyingFluid; + } + + /** + * @param amount the size of the returned FluidStack. + * @return a FluidStack of the Fluid which solidifies into the material. + */ + public FluidStack solidifiesFrom(int amount) { + return new FluidStack(solidifiesFrom(), amount); + } + + /** + * Sets the fluid that solidifies into the material. + * + * @param solidifyingFluid The Fluid which solidifies into the material. If left null, it will be left as the + * default value: the material's liquid. + */ + public void setSolidifyingFluid(@Nullable Fluid solidifyingFluid) { + this.solidifyingFluid = solidifyingFluid; + } } diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index ac915b45dc7..74239ff12ae 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -286,10 +286,10 @@ public static void processIngot(OrePrefix ingotPrefix, Material material, IngotP } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_INGOT) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(ingotPrefix, material)) .duration(20).EUt(VA[ULV]) .buildAndRegister(); @@ -424,10 +424,10 @@ public static void processNugget(OrePrefix orePrefix, Material material, DustPro .output(ingot, material) .buildAndRegister(); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(orePrefix, material, 9)) .duration((int) material.getMass()) .EUt(VA[ULV]) @@ -465,10 +465,11 @@ public static void processFrame(OrePrefix framePrefix, Material material, DustPr public static void processBlock(OrePrefix blockPrefix, Material material, DustProperty property) { ItemStack blockStack = OreDictUnifier.get(blockPrefix, material); long materialAmount = blockPrefix.getMaterialAmount(material); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_BLOCK) - .fluidInputs(material.getFluid((int) (materialAmount * L / M))) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom( + ((int) (materialAmount * L / M)))) .outputs(blockStack) .duration((int) material.getMass()).EUt(VA[ULV]) .buildAndRegister(); diff --git a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java index 24ec5349133..ddff63fd34a 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java @@ -200,11 +200,12 @@ public static void processGear(OrePrefix gearPrefix, Material material, DustProp } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { boolean isSmall = gearPrefix == OrePrefix.gearSmall; RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(isSmall ? MetaItems.SHAPE_MOLD_GEAR_SMALL : MetaItems.SHAPE_MOLD_GEAR) - .fluidInputs(material.getFluid(L * (isSmall ? 1 : 4))) + .fluidInputs( + material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * (isSmall ? 1 : 4))) .outputs(stack) .duration(isSmall ? 20 : 100) .EUt(VA[ULV]) @@ -285,10 +286,10 @@ public static void processLens(OrePrefix lensPrefix, Material material, GemPrope } public static void processPlate(OrePrefix platePrefix, Material material, DustProperty property) { - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_PLATE) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(platePrefix, material)) .duration(40) .EUt(VA[ULV]) @@ -399,10 +400,10 @@ public static void processRotor(OrePrefix rotorPrefix, Material material, IngotP 'S', new UnificationEntry(screw, material), 'R', new UnificationEntry(ring, material)); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_ROTOR) - .fluidInputs(material.getFluid(L * 4)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * 4)) .outputs(GTUtility.copy(stack)) .duration(120) .EUt(20) From b17be0df63a106f0f5943ea5924160dd933f526a Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:09:24 -0600 Subject: [PATCH 053/168] Fix reservoir hatch issues (#2349) --- .../MetaTileEntityReservoirHatch.java | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java index 9981538731d..e8cf6d7b59b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java @@ -63,7 +63,6 @@ public void update() { super.update(); if (!getWorld().isRemote) { fillContainerFromInternalTank(fluidTank); - fillInternalTankFromFluidContainer(fluidTank); if (getOffsetTimer() % 20 == 0) { fluidTank.refillWater(); } @@ -129,7 +128,7 @@ public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, Entity // Add input/output-specific widgets tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, true); + .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, false); builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) @@ -180,47 +179,39 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t private static class InfiniteWaterTank extends NotifiableFluidTank { - private final FluidStack BIG_WATER = new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT); - public InfiniteWaterTank(int capacity, MetaTileEntity entityToNotify) { super(capacity, entityToNotify, false); - setFluid(BIG_WATER); + // start with the full amount + setFluid(new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT)); + // don't allow external callers to fill this tank + setCanFill(false); } private void refillWater() { - if (BIG_WATER.amount != FLUID_AMOUNT) { - BIG_WATER.amount = FLUID_AMOUNT; - onContentsChanged(); + int fillAmount = Math.max(0, FLUID_AMOUNT - getFluidAmount()); + if (fillAmount > 0) { + // call super since our overrides don't allow any kind of filling + super.fillInternal(new FluidStack(FluidRegistry.WATER, fillAmount), true); } } @Override - public FluidStack drainInternal(int maxDrain, boolean doDrain) { - return new FluidStack(BIG_WATER, maxDrain); - } - - @Nullable - @Override - public FluidStack drainInternal(FluidStack resource, boolean doDrain) { - return new FluidStack(BIG_WATER, resource.amount); + public boolean canDrainFluidType(@Nullable FluidStack fluid) { + return fluid != null && fluid.getFluid() == FluidRegistry.WATER; } + // don't allow external filling @Override public int fillInternal(FluidStack resource, boolean doFill) { - return resource.amount; - } - - @Override - public boolean canDrainFluidType(@Nullable FluidStack fluid) { - return fluid != null && fluid.getFluid() == BIG_WATER.getFluid(); + return 0; } @Override public boolean canFillFluidType(FluidStack fluid) { - return fluid.getFluid() == BIG_WATER.getFluid(); + return false; } - // serialization is unnecessary here, it should always have the same amount of fluid + // serialization is unnecessary here, we can always recreate it completely full since it would refill anyway @Override public FluidTank readFromNBT(NBTTagCompound nbt) { return this; From d1a51795411dad5bf74b3c62de4436b0b4a56675 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:09:39 -0600 Subject: [PATCH 054/168] Fix LCE/ECE obstruction check (#2346) --- .../gregtech/api/util/RelativeDirection.java | 29 +++++++++++++++++++ .../MetaTileEntityLargeCombustionEngine.java | 23 ++++++++------- .../MetaTileEntityRotorHolder.java | 20 ++++++++----- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/api/util/RelativeDirection.java b/src/main/java/gregtech/api/util/RelativeDirection.java index 1e4b2102761..c55db969ee4 100644 --- a/src/main/java/gregtech/api/util/RelativeDirection.java +++ b/src/main/java/gregtech/api/util/RelativeDirection.java @@ -163,4 +163,33 @@ public static EnumFacing simulateAxisRotation(EnumFacing newFrontFacing, EnumFac return upwardsFacing.getOpposite(); } } + + /** + * Offset a BlockPos relatively in any direction by any amount. Pass negative values to offset down, right or + * backwards. + */ + public static BlockPos offsetPos(BlockPos pos, EnumFacing frontFacing, EnumFacing upwardsFacing, boolean isFlipped, + int upOffset, int leftOffset, int forwardOffset) { + if (upOffset == 0 && leftOffset == 0 && forwardOffset == 0) { + return pos; + } + + int oX = 0, oY = 0, oZ = 0; + final EnumFacing relUp = UP.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relUp.getXOffset() * upOffset; + oY += relUp.getYOffset() * upOffset; + oZ += relUp.getZOffset() * upOffset; + + final EnumFacing relLeft = LEFT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relLeft.getXOffset() * leftOffset; + oY += relLeft.getYOffset() * leftOffset; + oZ += relLeft.getZOffset() * leftOffset; + + final EnumFacing relForward = FRONT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relForward.getXOffset() * forwardOffset; + oY += relForward.getYOffset() * forwardOffset; + oZ += relForward.getZOffset() * forwardOffset; + + return pos.add(oX, oY, oZ); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java index 4b298f25cd0..7d58be463fe 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java @@ -16,6 +16,7 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; +import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.ICubeRenderer; @@ -28,7 +29,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; @@ -192,18 +192,19 @@ protected void formStructure(PatternMatchContext context) { } private boolean checkIntakesObstructed() { - EnumFacing facing = this.getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = this.getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - // Skip the controller block itself - if (x == 0 && y == 0) + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + if (left == 0 && up == 0) { + // Skip the controller block itself continue; - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = this.getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, this.getWorld(), blockPos)) + } + + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), getFrontFacing(), getUpwardsFacing(), isFlipped(), up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return true; + } } } return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java index e36b9bb24d4..d78b7fe5042 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java @@ -12,6 +12,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.RelativeDirection; import gregtech.client.renderer.texture.Textures; import gregtech.common.items.behaviors.AbstractMaterialPartBehavior; import gregtech.common.items.behaviors.TurbineRotorBehavior; @@ -163,14 +164,17 @@ public boolean isFrontFaceFree() { } private boolean checkTurbineFaceFree() { - EnumFacing facing = getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, getWorld(), blockPos)) { + final EnumFacing front = getFrontFacing(); + // this can be anything really, as long as it is not up/down when on Y axis + final EnumFacing upwards = front.getAxis() == EnumFacing.Axis.Y ? EnumFacing.NORTH : EnumFacing.UP; + + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + // flip doesn't affect anything here since we are checking a square anyway + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), front, upwards, false, up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return false; } } From 2f79ee8cc6a9c1a42db9f143d10b8f4e314f9c00 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:11:47 -0700 Subject: [PATCH 055/168] Fix electric tool damage config innacuracy (#2350) --- src/main/java/gregtech/api/items/toolitem/ToolHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index 2e0a3335df0..23d3145ca9b 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -270,7 +270,7 @@ public static void damageItem(@NotNull ItemStack stack, @Nullable EntityLivingBa if (electricItem != null) { electricItem.discharge(electricDamage, tool.getElectricTier(), true, false, false); if (electricItem.getCharge() > 0 && - random.nextInt(100) > ConfigHolder.tools.rngDamageElectricTools) { + random.nextInt(100) >= ConfigHolder.tools.rngDamageElectricTools) { return; } } else { From 688e537f6bddf400e0939220c3c7b81fa5737b3f Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:15:54 -0500 Subject: [PATCH 056/168] weaken recipe logic type in WorkableTieredMetaTileEntity (#2342) --- .../metatileentity/WorkableTieredMetaTileEntity.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java index 69c42322da8..5e648be0f60 100644 --- a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java @@ -1,7 +1,12 @@ package gregtech.api.metatileentity; import gregtech.api.GTValues; -import gregtech.api.capability.impl.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.EnergyContainerHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.multiblock.ICleanroomProvider; import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; @@ -34,7 +39,7 @@ public abstract class WorkableTieredMetaTileEntity extends TieredMetaTileEntity implements IDataInfoProvider, ICleanroomReceiver { - protected final RecipeLogicEnergy workable; + protected final AbstractRecipeLogic workable; protected final RecipeMap recipeMap; protected final ICubeRenderer renderer; @@ -63,7 +68,7 @@ public WorkableTieredMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap reinitializeEnergyContainer(); } - protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { + protected AbstractRecipeLogic createWorkable(RecipeMap recipeMap) { return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } From 80aa0b03815596b7139562b395479bb253287e0e Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 18 Jan 2024 23:48:58 -0700 Subject: [PATCH 057/168] Fix Issues with Fusion Reactor Overclocking (#2352) --- .../multi/electric/MetaTileEntityFusionReactor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 90b8b70886c..35c06785bab 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -640,7 +640,7 @@ protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipeProper // MK3 reactor can overclock a MK2 recipe once, or a MK1 recipe twice. long euToStart = storage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); int fusionTier = FusionEUToStartProperty.getFusionTier(euToStart); - if (fusionTier != 0) fusionTier -= MetaTileEntityFusionReactor.this.tier; + if (fusionTier != 0) fusionTier = MetaTileEntityFusionReactor.this.tier - fusionTier; values[2] = Math.min(fusionTier, values[2]); } From e682821057e5c493ea9720deba5fb34059b5b259 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:14:04 -0600 Subject: [PATCH 058/168] Separate PSS average IO into in and out (#2353) --- .../MetaTileEntityPowerSubstation.java | 85 +++++++++++-------- .../specific/DriverPowerSubstation.java | 11 ++- .../resources/assets/gregtech/lang/en_us.lang | 6 +- 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java index c6ee87449d2..7814f3dccc9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java @@ -81,8 +81,10 @@ public class MetaTileEntityPowerSubstation extends MultiblockWithDisplayBase private boolean isActive, isWorkingEnabled = true; // Stats tracked for UI display - private long netIOLastSec; - private long averageIOLastSec; + private long netInLastSec; + private long averageInLastSec; + private long netOutLastSec; + private long averageOutLastSec; public MetaTileEntityPowerSubstation(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -138,8 +140,10 @@ public void invalidateStructure() { inputHatches = null; outputHatches = null; passiveDrain = 0; - netIOLastSec = 0; - averageIOLastSec = 0; + netInLastSec = 0; + averageInLastSec = 0; + netOutLastSec = 0; + averageOutLastSec = 0; super.invalidateStructure(); } @@ -149,25 +153,27 @@ protected void updateFormedValid() { if (getOffsetTimer() % 20 == 0) { // active here is just used for rendering setActive(energyBank.hasEnergy()); - averageIOLastSec = netIOLastSec / 20; - netIOLastSec = 0; + averageInLastSec = netInLastSec / 20; + averageOutLastSec = netOutLastSec / 20; + netInLastSec = 0; + netOutLastSec = 0; } if (isWorkingEnabled()) { // Bank from Energy Input Hatches long energyBanked = energyBank.fill(inputHatches.getEnergyStored()); inputHatches.changeEnergy(-energyBanked); - netIOLastSec += energyBanked; + netInLastSec += energyBanked; // Passive drain long energyPassiveDrained = energyBank.drain(getPassiveDrain()); - netIOLastSec -= energyPassiveDrained; + netOutLastSec += energyPassiveDrained; // Debank to Dynamo Hatches long energyDebanked = energyBank .drain(outputHatches.getEnergyCapacity() - outputHatches.getEnergyStored()); outputHatches.changeEnergy(energyDebanked); - netIOLastSec -= energyDebanked; + netOutLastSec += energyDebanked; } } } @@ -359,44 +365,45 @@ protected void addDisplayText(List textList) { "gregtech.multiblock.power_substation.passive_drain", passiveDrain)); - // Average I/O line - TextFormatting averageIOColor = TextFormatting.GRAY; - if (isActive() && isWorkingEnabled() && averageIOLastSec == 0) { - // only set to yellow on zero if the machine is on, avoids a yellow "warning" - // color when the machine is first formed and not yet plugged in. - averageIOColor = TextFormatting.YELLOW; - } else if (averageIOLastSec > 0) { - averageIOColor = TextFormatting.GREEN; - } else if (averageIOLastSec < 0) { - averageIOColor = TextFormatting.RED; - } - - ITextComponent averageIO = TextComponentUtil.stringWithColor( - averageIOColor, - TextFormattingUtil.formatNumbers(averageIOLastSec) + " EU/t"); - + // Average EU IN line + ITextComponent avgValue = TextComponentUtil.stringWithColor( + TextFormatting.GREEN, + TextFormattingUtil.formatNumbers(averageInLastSec) + " EU/t"); ITextComponent base = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io", - averageIO); - + "gregtech.multiblock.power_substation.average_in", + avgValue); ITextComponent hover = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io_hover"); + "gregtech.multiblock.power_substation.average_in_hover"); + tl.add(TextComponentUtil.setHover(base, hover)); + + // Average EU OUT line + avgValue = TextComponentUtil.stringWithColor( + TextFormatting.RED, + TextFormattingUtil.formatNumbers(averageOutLastSec) + " EU/t"); + base = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out", + avgValue); + hover = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out_hover"); tl.add(TextComponentUtil.setHover(base, hover)); // Time to fill/drain line - if (averageIOLastSec > 0) { + if (averageInLastSec > averageOutLastSec) { ITextComponent timeToFill = getTimeToFillDrainText(energyCapacity.subtract(energyStored) - .divide(BigInteger.valueOf(averageIOLastSec * 20))); + .divide(BigInteger.valueOf((averageInLastSec - averageOutLastSec) * 20))); TextComponentUtil.setColor(timeToFill, TextFormatting.GREEN); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.power_substation.time_to_fill", timeToFill)); - } else if (averageIOLastSec < 0) { + } else if (averageInLastSec < averageOutLastSec) { ITextComponent timeToDrain = getTimeToFillDrainText( - energyStored.divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20))); + energyStored.divide(BigInteger.valueOf( + (averageOutLastSec - averageInLastSec) * 20))); TextComponentUtil.setColor(timeToDrain, TextFormatting.RED); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -412,9 +419,9 @@ protected void addDisplayText(List textList) { protected void addWarningText(List textList) { super.addWarningText(textList); if (isStructureFormed()) { - if (averageIOLastSec < 0) { // decreasing + if (averageInLastSec < averageOutLastSec) { // decreasing BigInteger timeToDrainSeconds = energyBank.getStored() - .divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20)); + .divide(BigInteger.valueOf((averageOutLastSec - averageInLastSec) * 20)); if (timeToDrainSeconds.compareTo(BigInteger.valueOf(60 * 60)) < 0) { // less than 1 hour left textList.add(TextComponentUtil.translationWithColor( TextFormatting.YELLOW, @@ -550,8 +557,12 @@ public String getCapacity() { return TextFormattingUtil.formatNumbers(energyBank.getCapacity()); } - public long getAverageIOLastSec() { - return averageIOLastSec; + public long getAverageInLastSec() { + return averageInLastSec; + } + + public long getAverageOutLastSec() { + return averageOutLastSec; } @Override diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java index 509de932b1b..53a506db55b 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java @@ -63,9 +63,14 @@ public Object[] getPassiveDrain(final Context context, final Arguments args) { return new Object[] { tileEntity.getPassiveDrain() }; } - @Callback(doc = "function():number -- Returns the average net EU/t in or out over the last second.") - public Object[] getAverageIOLastSec(final Context context, final Arguments args) { - return new Object[] { tileEntity.getAverageIOLastSec() }; + @Callback(doc = "function():number -- Returns the average EU/t in over the last second.") + public Object[] getAverageInLastSec(final Context context, final Arguments args) { + return new Object[] { tileEntity.getAverageInLastSec() }; + } + + @Callback(doc = "function():number -- Returns the average EU/t out over the last second.") + public Object[] getAverageOutLastSec(final Context context, final Arguments args) { + return new Object[] { tileEntity.getAverageOutLastSec() }; } } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 0a99c369d6a..b102b23fcff 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5649,8 +5649,10 @@ gregtech.multiblock.computation.not_enough_computation=Machine needs more comput gregtech.multiblock.power_substation.stored=Stored: %s gregtech.multiblock.power_substation.capacity=Capacity: %s gregtech.multiblock.power_substation.passive_drain=Passive Drain: %s -gregtech.multiblock.power_substation.average_io=Avg. I/O: %s -gregtech.multiblock.power_substation.average_io_hover=The average change in energy of the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_in=Avg. EU IN: %s +gregtech.multiblock.power_substation.average_out=Avg. EU OUT: %s +gregtech.multiblock.power_substation.average_in_hover=The average EU/t input into the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_out_hover=The average EU/t output from the Power Substation's internal energy bank, both passive loss and outputs gregtech.multiblock.power_substation.time_to_fill=Time to fill: %s gregtech.multiblock.power_substation.time_to_drain=Time to drain: %s gregtech.multiblock.power_substation.time_seconds=%s Seconds From 627d6f14bc499f4147c36ce9e401bf877a0ada33 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:46:14 -0500 Subject: [PATCH 059/168] fix gt tile entities not rendering in AE2 pattern outputs (#2319) --- src/main/java/gregtech/api/GTValues.java | 3 +- .../gregtech/api/util/ModCompatibility.java | 60 +------ .../java/gregtech/client/ClientProxy.java | 11 +- .../renderer/handler/CCLBlockRenderer.java | 10 +- .../renderer/handler/FacadeRenderer.java | 4 +- .../handler/MetaTileEntityRenderer.java | 4 +- .../client/renderer/pipe/PipeRenderer.java | 4 +- .../client/utils/ItemRenderCompat.java | 170 ++++++++++++++++++ 8 files changed, 199 insertions(+), 67 deletions(-) create mode 100644 src/main/java/gregtech/client/utils/ItemRenderCompat.java diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 7a1b5d34f4f..0d57fc6d5f9 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -158,7 +158,8 @@ public class GTValues { MODID_TCON = "tconstruct", MODID_PROJRED_CORE = "projectred-core", MODID_RC = "railcraft", - MODID_CHISEL = "chisel"; + MODID_CHISEL = "chisel", + MODID_RS = "refinedstorage"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/util/ModCompatibility.java b/src/main/java/gregtech/api/util/ModCompatibility.java index 9881948147d..d6b627d3b6a 100644 --- a/src/main/java/gregtech/api/util/ModCompatibility.java +++ b/src/main/java/gregtech/api/util/ModCompatibility.java @@ -1,66 +1,22 @@ package gregtech.api.util; -import gregtech.api.util.world.DummyWorld; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Objects; +import org.jetbrains.annotations.ApiStatus; @SideOnly(Side.CLIENT) public class ModCompatibility { - private static RefinedStorage refinedStorage; - - public static void initCompat() { - try { - Class itemClass = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); - refinedStorage = new RefinedStorage(itemClass); - GTLog.logger.info("RefinedStorage found; enabling integration."); - } catch (ClassNotFoundException ignored) { - GTLog.logger.info("RefinedStorage not found; skipping integration."); - } catch (Throwable exception) { - GTLog.logger.error("Failed to enable RefinedStorage integration", exception); - } - } - + /** + * @deprecated Use {@link ItemRenderCompat#getRepresentedStack(ItemStack)} + */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + @Deprecated public static ItemStack getRealItemStack(ItemStack itemStack) { - if (refinedStorage != null && RefinedStorage.canHandleItemStack(itemStack)) { - return refinedStorage.getRealItemStack(itemStack); - } - return itemStack; - } - - private static class RefinedStorage { - - private final Method getPatternFromCacheMethod; - private final Method getOutputsMethod; - - public RefinedStorage(Class itemPatternClass) throws ReflectiveOperationException { - this.getPatternFromCacheMethod = itemPatternClass.getMethod("getPatternFromCache", World.class, - ItemStack.class); - this.getOutputsMethod = getPatternFromCacheMethod.getReturnType().getMethod("getOutputs"); - } - - public static boolean canHandleItemStack(ItemStack itemStack) { - ResourceLocation registryName = Objects.requireNonNull(itemStack.getItem().getRegistryName()); - return registryName.getNamespace().equals("refinedstorage") && - registryName.getPath().equals("pattern"); - } - - public ItemStack getRealItemStack(ItemStack itemStack) { - try { - Object craftingPattern = getPatternFromCacheMethod.invoke(null, DummyWorld.INSTANCE, itemStack); - List outputs = (List) getOutputsMethod.invoke(craftingPattern); - return outputs.isEmpty() ? itemStack : outputs.get(0); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException("Failed to obtain item from ItemPattern", ex); - } - } + return ItemRenderCompat.getRepresentedStack(itemStack); } } diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 0210563b18c..2b7207a232d 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -10,12 +10,17 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.IBlockOre; -import gregtech.api.util.ModCompatibility; import gregtech.client.model.customtexture.CustomTextureModelHandler; import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; import gregtech.client.renderer.handler.MetaTileEntityRenderer; -import gregtech.client.renderer.pipe.*; +import gregtech.client.renderer.pipe.CableRenderer; +import gregtech.client.renderer.pipe.FluidPipeRenderer; +import gregtech.client.renderer.pipe.ItemPipeRenderer; +import gregtech.client.renderer.pipe.LaserPipeRenderer; +import gregtech.client.renderer.pipe.OpticalPipeRenderer; +import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.client.utils.ItemRenderCompat; import gregtech.client.utils.TooltipHelper; import gregtech.common.CommonProxy; import gregtech.common.ConfigHolder; @@ -101,7 +106,7 @@ public void onLoad() { public void onPostLoad() { super.onPostLoad(); TerminalRegistry.initTerminalFiles(); - ModCompatibility.initCompat(); + ItemRenderCompat.init(); FacadeRenderer.init(); } diff --git a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java index 5dabff41d6a..e2046685f86 100644 --- a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java @@ -2,9 +2,9 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.ICCLBlockRenderer; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -60,10 +60,10 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); - if (stack.getItem() instanceof ItemBlock && - ((ItemBlock) stack.getItem()).getBlock() instanceof ICCLBlockRenderer) { - ((ICCLBlockRenderer) ((ItemBlock) stack.getItem()).getBlock()).renderItem(stack, transformType); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); + if (stack.getItem() instanceof ItemBlock itemBlock && + itemBlock.getBlock() instanceof ICCLBlockRenderer renderer) { + renderer.renderItem(stack, transformType); } } diff --git a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java index fcd0c3ba523..6db1848659a 100644 --- a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java @@ -2,11 +2,11 @@ import gregtech.api.cover.CoverUtil; import gregtech.api.items.metaitem.MetaItem; -import gregtech.api.util.ModCompatibility; import gregtech.client.model.pipeline.VertexLighterFlatSpecial; import gregtech.client.model.pipeline.VertexLighterSmoothAoSpecial; import gregtech.client.utils.AdvCCRSConsumer; import gregtech.client.utils.FacadeBlockAccess; +import gregtech.client.utils.ItemRenderCompat; import gregtech.common.covers.facade.FacadeHelper; import gregtech.common.items.behaviors.FacadeItem; @@ -82,7 +82,7 @@ public static void init() { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack itemStack = ModCompatibility.getRealItemStack(rawStack); + ItemStack itemStack = ItemRenderCompat.getRepresentedStack(rawStack); if (!(itemStack.getItem() instanceof MetaItem)) { return; } diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java index 9436d30dc8d..846bcc08860 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java @@ -4,9 +4,9 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.BufferBuilder; @@ -72,7 +72,7 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(stack); if (metaTileEntity == null) { return; diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java index d16ca9ace07..e3195dba22c 100644 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java @@ -11,9 +11,9 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -150,7 +150,7 @@ public abstract void buildRenderer(PipeRenderContext renderContext, BlockPipe + * Primarily used to retrieve the output stack from AE2 or RS Patterns. + * + * @param stack the stack to retrieve from + * @return the actual represented ItemStack + */ + public static @NotNull ItemStack getRepresentedStack(@NotNull ItemStack stack) { + if (ae2Handler != null && ae2Handler.canHandleStack(stack)) { + return ae2Handler.getActualStack(stack); + } + if (rsHandler != null && rsHandler.canHandleStack(stack)) { + return rsHandler.getActualStack(stack); + } + return stack; + } + + /** + * An extractor to retrieve a represented stack from an ItemStack + */ + public interface RepresentativeStackExtractor { + + /** + * @param stack the stack to test + * @return if the extractor can handle the stack + */ + boolean canHandleStack(@NotNull ItemStack stack); + + /** + * @param stack the stack to retrieve from + * @return the represented stack + */ + @NotNull + ItemStack getActualStack(@NotNull ItemStack stack); + } + + /** + * Extracts the output stack from AE2 Patterns + */ + private static final class AE2StackExtractor implements RepresentativeStackExtractor { + + public static @Nullable ItemRenderCompat.AE2StackExtractor create() { + if (!Loader.isModLoaded(GTValues.MODID_APPENG)) return null; + GTLog.logger.info("AppliedEnergistics2 found; enabling render integration."); + return new AE2StackExtractor(); + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return stack.getItem() instanceof ItemEncodedPattern; + } + + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + if (stack.getItem() instanceof ItemEncodedPattern encodedPattern) { + return encodedPattern.getOutput(stack); + } + return stack; + } + } + + /** + * Extracts the output stack from RS Patterns + */ + @SuppressWarnings("ClassCanBeRecord") + private static final class RSStackExtractor implements RepresentativeStackExtractor { + + private final MethodHandle getPatternFromCacheHandle; + private final MethodHandle getOutputsHandle; + private final Class itemPatternClass; + + private RSStackExtractor(MethodHandle getPatternFromCacheHandle, MethodHandle getOutputsHandle, + Class itemPatternClass) { + this.getPatternFromCacheHandle = getPatternFromCacheHandle; + this.getOutputsHandle = getOutputsHandle; + this.itemPatternClass = itemPatternClass; + } + + public static @Nullable ItemRenderCompat.RSStackExtractor create() { + if (!Loader.isModLoaded(GTValues.MODID_RS)) return null; + + Class clazz; + try { + clazz = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); + GTLog.logger.info("RefinedStorage found; enabling render integration."); + } catch (ClassNotFoundException ignored) { + GTLog.logger.error("RefinedStorage classes not found; skipping render integration."); + return null; + } + + try { + Method method = clazz.getMethod("getPatternFromCache", World.class, ItemStack.class); + + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + + MethodHandle getPatternFromCacheHandle = lookup.unreflect(method); + + method = method.getReturnType().getMethod("getOutputs"); + MethodHandle getOutputsHandle = lookup.unreflect(method); + + return new RSStackExtractor(getPatternFromCacheHandle, getOutputsHandle, clazz); + } catch (NoSuchMethodException | IllegalAccessException e) { + GTLog.logger.error("Failed to enable RefinedStorage integration", e); + return null; + } + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return itemPatternClass.isAssignableFrom(stack.getItem().getClass()); + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + + List outputs; + try { + // ItemPattern.getPatternFromCache: (World, ItemStack) -> CraftingPattern + Object craftingPattern = getPatternFromCacheHandle.invoke(DummyWorld.INSTANCE, stack); + // CraftingPattern#getOutputs: () -> List + outputs = (List) getOutputsHandle.invoke(craftingPattern); + } catch (Throwable e) { + GTLog.logger.error("Failed to obtain item from ItemPattern", e); + return stack; + } + + if (outputs.isEmpty()) { + return stack; + } + return outputs.get(0); + } + } +} From 4ab90cf12d478083ed045aa984ff6ff214a10ae1 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:16:51 -0600 Subject: [PATCH 060/168] Cherrypick of #2325 --- .../api/recipes/machines/RecipeMapResearchStation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/machines/RecipeMapResearchStation.java b/src/main/java/gregtech/api/recipes/machines/RecipeMapResearchStation.java index f75138d6f27..02c0c56df1d 100644 --- a/src/main/java/gregtech/api/recipes/machines/RecipeMapResearchStation.java +++ b/src/main/java/gregtech/api/recipes/machines/RecipeMapResearchStation.java @@ -35,11 +35,11 @@ public ModularUI.Builder createJeiUITemplate(IItemHandlerModifiable importItems, GuiTextures.PROGRESS_BAR_RESEARCH_STATION_1, ProgressWidget.MoveType.HORIZONTAL)) .widget(new ProgressWidget(pairedSuppliers.getRight(), 119, 32, 10, 18, GuiTextures.PROGRESS_BAR_RESEARCH_STATION_2, ProgressWidget.MoveType.VERTICAL_DOWNWARDS)) - .widget(new SlotWidget(importItems, 0, 115, 50, true, true) + .widget(new SlotWidget(exportItems, 0, 115, 50, true, true) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.DATA_ORB_OVERLAY)) .widget(new SlotWidget(importItems, 1, 43, 21, true, true) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.SCANNER_OVERLAY)) - .widget(new SlotWidget(exportItems, 0, 97, 21, true, true) + .widget(new SlotWidget(importItems, 0, 97, 21, true, true) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.RESEARCH_STATION_OVERLAY)); } } From 971d45861f77ec59e98f08952117ee96fded035b Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:48:20 -0600 Subject: [PATCH 061/168] 2.8.6 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7b97b1fe4f9..d92a78eb1a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.5-beta +modVersion = 2.8.6-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From 9f96b7333f22aaba67648fc229444b5333d91363 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 28 Jan 2024 19:02:48 -0700 Subject: [PATCH 062/168] Fix Player Unable to Climb Frames on Certain Pipes (#2359) --- src/main/java/gregtech/common/pipelike/cable/BlockCable.java | 1 + .../java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java index d384e22e608..20c8c686fe4 100644 --- a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java +++ b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java @@ -163,6 +163,7 @@ public boolean isHoldingPipe(EntityPlayer player) { @Override public void onEntityCollision(World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state, @NotNull Entity entityIn) { + super.onEntityCollision(worldIn, pos, state, entityIn); if (worldIn.isRemote) return; Insulation insulation = getPipeTileEntity(worldIn, pos).getPipeType(); if (insulation.insulationLevel == -1 && entityIn instanceof EntityLivingBase) { diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java b/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java index f4e4975fa6c..7449f65d211 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java @@ -129,6 +129,7 @@ public boolean isHoldingPipe(EntityPlayer player) { @Override public void onEntityCollision(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state, @NotNull Entity entityIn) { + super.onEntityCollision(worldIn, pos, state, entityIn); if (worldIn.isRemote) return; TileEntityFluidPipe pipe = (TileEntityFluidPipe) getPipeTileEntity(worldIn, pos); if (pipe instanceof TileEntityFluidPipeTickable && pipe.getFrameMaterial() == null && From c0615f172cce24d04708c121c96cad1f2a9feadb Mon Sep 17 00:00:00 2001 From: mtbo <111296252+loxoDev@users.noreply.github.com> Date: Mon, 29 Jan 2024 03:04:00 +0100 Subject: [PATCH 063/168] Fix recipe properties offsetting info text too much (#2360) --- .../api/recipes/recipeproperties/CleanroomProperty.java | 7 +++++++ .../api/recipes/recipeproperties/PrimitiveProperty.java | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java index ccbe97bdc17..2152e3a3e43 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java @@ -32,6 +32,13 @@ public void drawInfo(@NotNull Minecraft minecraft, int x, int y, int color, Obje minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.cleanroom", getName(type)), x, y, color); } + @Override + public int getInfoHeight(Object value) { + CleanroomType type = castValue(value); + if (type == null) return 0; + return super.getInfoHeight(value); + } + @NotNull private static String getName(@NotNull CleanroomType value) { String name = I18n.format(value.getTranslationKey()); diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java index 524fd7180fe..6419cd2aab0 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java @@ -24,6 +24,11 @@ public static PrimitiveProperty getInstance() { @Override public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) {} + @Override + public int getInfoHeight(Object value) { + return 0; + } + @Override public boolean hideTotalEU() { return true; From 2957212f671240727eba2c20e66535e78561f306 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:54:59 -0600 Subject: [PATCH 064/168] Fix central monitor jei page (#2364) --- src/main/java/gregtech/client/utils/RenderUtil.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index ed91be4e57e..070ff054c10 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -153,6 +153,9 @@ public static void useStencil(Runnable mask, Runnable renderInMask, boolean shou renderInMask.run(); GL11.glDisable(GL11.GL_STENCIL_TEST); + GL11.glClearStencil(0); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + GL11.glStencilFunc(GL11.GL_ALWAYS, 0, 0xFF); } public static void useLightMap(float x, float y, Runnable codeBlock) { From 5d3ef8aec181354898fe75950ebaa3d083e929a9 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:55:41 -0700 Subject: [PATCH 065/168] Fix unlocalized name of GT fluids in drums (#2361) --- .../metatileentities/storage/MetaTileEntityDrum.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index ae83ad54a49..321012fcf8f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -44,6 +44,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -97,7 +98,7 @@ protected void initializeInventory() { IPropertyFluidFilter filter = this.material.getProperty(PropertyKey.FLUID_PIPE); if (filter == null) { throw new IllegalArgumentException( - String.format("Material %s requires FluidPipePropety for Drums", material)); + String.format("Material %s requires FluidPipeProperty for Drums", material)); } this.fluidInventory = this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(filter); } @@ -129,7 +130,7 @@ public ICapabilityProvider initItemStackCapabilities(ItemStack itemStack) { } @Override - public void writeInitialSyncData(PacketBuffer buf) { + public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); FluidStack fluidStack = fluidTank.getFluid(); buf.writeBoolean(fluidStack != null); @@ -142,7 +143,7 @@ public void writeInitialSyncData(PacketBuffer buf) { } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); FluidStack fluidStack = null; if (buf.readBoolean()) { @@ -156,7 +157,7 @@ public void receiveInitialSyncData(PacketBuffer buf) { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_AUTO_OUTPUT) { this.isAutoOutput = buf.readBoolean(); @@ -266,7 +267,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(tagCompound.getCompoundTag("Fluid")); if (fluidStack == null) return; tooltip.add(I18n.format("gregtech.machine.fluid_tank.fluid", fluidStack.amount, - I18n.format(fluidStack.getUnlocalizedName()))); + fluidStack.getFluid().getLocalizedName(fluidStack))); } } From 1cbc1aa05723810f7e09ddfa7b13dad512a0ae4d Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:55:56 -0600 Subject: [PATCH 066/168] Add OpenComputers functions for maintenance problems (#2356) --- .../drivers/DriverRecipeMapMultiblockController.java | 5 +++++ .../drivers/specific/DriverPowerSubstation.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java b/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java index 344b1d6b806..7db4e9bd232 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java @@ -152,5 +152,10 @@ public Object[] getInputTank(final Context context, final Arguments args) { public Object[] getOutputTank(final Context context, final Arguments args) { return getTank(tileEntity.getOutputFluidInventory()); } + + @Callback(doc = "function():number -- Gets the number of maintenance problems.") + public Object[] getMaintenanceProblems(final Context context, final Arguments args) { + return new Object[] { tileEntity.getNumMaintenanceProblems() }; + } } } diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java index 53a506db55b..956ec6a760c 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java @@ -72,5 +72,10 @@ public Object[] getAverageInLastSec(final Context context, final Arguments args) public Object[] getAverageOutLastSec(final Context context, final Arguments args) { return new Object[] { tileEntity.getAverageOutLastSec() }; } + + @Callback(doc = "function():number -- Gets the number of maintenance problems.") + public Object[] getMaintenanceProblems(final Context context, final Arguments args) { + return new Object[] { tileEntity.getNumMaintenanceProblems() }; + } } } From fb230721bd2d5a28539e2bdd5ca9b65afb0e8ceb Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:04:24 -0600 Subject: [PATCH 067/168] Add Powderbarrel and ITNT (#2314) --- .../renderer/handler/GTExplosiveRenderer.java | 81 ++++++++ .../java/gregtech/common/CommonProxy.java | 4 + .../java/gregtech/common/EventHandlers.java | 12 ++ .../java/gregtech/common/MetaEntities.java | 9 + .../gregtech/common/blocks/MetaBlocks.java | 10 + .../blocks/explosive/BlockGTExplosive.java | 175 ++++++++++++++++++ .../common/blocks/explosive/BlockITNT.java | 40 ++++ .../blocks/explosive/BlockPowderbarrel.java | 42 +++++ .../blocks/material/GTBlockMaterials.java | 18 ++ .../common/entities/EntityGTExplosive.java | 136 ++++++++++++++ .../gregtech/common/entities/ITNTEntity.java | 41 ++++ .../common/entities/PowderbarrelEntity.java | 36 ++++ .../items/behaviors/LighterBehaviour.java | 10 +- .../forestry/bees/GTBeeDefinition.java | 4 +- .../loaders/recipe/CraftingRecipeLoader.java | 5 + .../recipe/chemistry/ReactorRecipes.java | 8 + .../handlers/MaterialRecipeHandler.java | 19 +- .../assets/gregtech/blockstates/itnt.json | 16 ++ .../gregtech/blockstates/powderbarrel.json | 14 ++ .../resources/assets/gregtech/lang/en_us.lang | 11 ++ .../gregtech/textures/blocks/misc/itnt.png | Bin 0 -> 212 bytes .../textures/blocks/misc/powderbarrel.png | Bin 0 -> 243 bytes src/main/resources/gregtech_at.cfg | 3 + 23 files changed, 688 insertions(+), 6 deletions(-) create mode 100644 src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java create mode 100644 src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java create mode 100644 src/main/java/gregtech/common/blocks/explosive/BlockITNT.java create mode 100644 src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java create mode 100644 src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java create mode 100644 src/main/java/gregtech/common/entities/EntityGTExplosive.java create mode 100644 src/main/java/gregtech/common/entities/ITNTEntity.java create mode 100644 src/main/java/gregtech/common/entities/PowderbarrelEntity.java create mode 100644 src/main/resources/assets/gregtech/blockstates/itnt.json create mode 100644 src/main/resources/assets/gregtech/blockstates/powderbarrel.json create mode 100644 src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png diff --git a/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java new file mode 100644 index 00000000000..4b0efe1ae63 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java @@ -0,0 +1,81 @@ +package gregtech.client.renderer.handler; + +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +@SideOnly(Side.CLIENT) +public class GTExplosiveRenderer extends Render { + + public GTExplosiveRenderer(RenderManager renderManager) { + super(renderManager); + this.shadowSize = 0.5F; + } + + @Override + public void doRender(@NotNull T entity, double x, double y, double z, float entityYaw, float partialTicks) { + BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher(); + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y + 0.5F, (float) z); + float f2; + if ((float) entity.getFuse() - partialTicks + 1.0F < 10.0F) { + f2 = 1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 10.0F; + f2 = MathHelper.clamp(f2, 0.0F, 1.0F); + f2 *= f2; + f2 *= f2; + float f1 = 1.0F + f2 * 0.3F; + GlStateManager.scale(f1, f1, f1); + } + + f2 = (1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 100.0F) * 0.8F; + this.bindEntityTexture(entity); + GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + + IBlockState state = entity.getExplosiveState(); + brd.renderBlockBrightness(state, entity.getBrightness()); + GlStateManager.translate(0.0F, 0.0F, 1.0F); + if (this.renderOutlines) { + GlStateManager.enableColorMaterial(); + GlStateManager.enableOutlineMode(this.getTeamColor(entity)); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.disableOutlineMode(); + GlStateManager.disableColorMaterial(); + } else if (entity.getFuse() / 5 % 2 == 0) { + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.DST_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, f2); + GlStateManager.doPolygonOffset(-3.0F, -3.0F); + GlStateManager.enablePolygonOffset(); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.doPolygonOffset(0.0F, 0.0F); + GlStateManager.disablePolygonOffset(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + } + + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + + @Override + protected ResourceLocation getEntityTexture(@NotNull T entity) { + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } +} diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index f8a956e201b..b9927847cd4 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -153,6 +153,8 @@ public static void registerBlocks(RegistryEvent.Register event) { registry.register(RUBBER_WOOD_DOOR); registry.register(TREATED_WOOD_DOOR); registry.register(BRITTLE_CHARCOAL); + registry.register(POWDERBARREL); + registry.register(ITNT); registry.register(METAL_SHEET); registry.register(LARGE_METAL_SHEET); registry.register(STUDS); @@ -273,6 +275,8 @@ public static void registerItems(RegistryEvent.Register event) { registry.register(createItemBlock(RUBBER_LOG, ItemBlock::new)); registry.register(createItemBlock(RUBBER_LEAVES, ItemBlock::new)); registry.register(createItemBlock(RUBBER_SAPLING, ItemBlock::new)); + registry.register(createItemBlock(POWDERBARREL, ItemBlock::new)); + registry.register(createItemBlock(ITNT, ItemBlock::new)); for (BlockCompressed block : COMPRESSED_BLOCKS) { registry.register(createItemBlock(block, b -> new MaterialItemBlock(b, OrePrefix.block))); diff --git a/src/main/java/gregtech/common/EventHandlers.java b/src/main/java/gregtech/common/EventHandlers.java index da32dd83ca5..588909961e5 100644 --- a/src/main/java/gregtech/common/EventHandlers.java +++ b/src/main/java/gregtech/common/EventHandlers.java @@ -14,6 +14,7 @@ import gregtech.api.util.GTUtility; import gregtech.api.util.VirtualTankRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData; +import gregtech.common.entities.EntityGTExplosive; import gregtech.common.items.MetaItems; import gregtech.common.items.armor.IStepAssist; import gregtech.common.items.armor.PowerlessJetpack; @@ -26,6 +27,7 @@ import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; @@ -48,6 +50,7 @@ import net.minecraftforge.event.entity.player.AdvancementEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; +import net.minecraftforge.event.world.ExplosionEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fml.common.Mod; @@ -373,4 +376,13 @@ public static void onFurnaceFuelBurnTime(FurnaceFuelBurnTimeEvent event) { event.setBurnTime(6400); } } + + @SubscribeEvent + public static void onExplosionDetonate(ExplosionEvent.Detonate event) { + if (event.getExplosion().exploder instanceof EntityGTExplosive explosive) { + if (explosive.dropsAllBlocks()) { + event.getAffectedEntities().removeIf(entity -> entity instanceof EntityItem); + } + } + } } diff --git a/src/main/java/gregtech/common/MetaEntities.java b/src/main/java/gregtech/common/MetaEntities.java index 00efb35f87d..965ce3bfb18 100644 --- a/src/main/java/gregtech/common/MetaEntities.java +++ b/src/main/java/gregtech/common/MetaEntities.java @@ -4,10 +4,13 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.handler.DynamiteRenderer; import gregtech.client.renderer.handler.GTBoatRenderer; +import gregtech.client.renderer.handler.GTExplosiveRenderer; import gregtech.client.renderer.handler.PortalRenderer; import gregtech.common.entities.DynamiteEntity; import gregtech.common.entities.GTBoatEntity; +import gregtech.common.entities.ITNTEntity; import gregtech.common.entities.PortalEntity; +import gregtech.common.entities.PowderbarrelEntity; import net.minecraft.client.Minecraft; import net.minecraftforge.fml.client.registry.RenderingRegistry; @@ -24,6 +27,10 @@ public static void init() { GregTechAPI.instance, 64, 5, true); EntityRegistry.registerModEntity(GTUtility.gregtechId("gtboat"), GTBoatEntity.class, "GTBoat", 3, GregTechAPI.instance, 64, 2, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("powderbarrel"), PowderbarrelEntity.class, "Powderbarrel", + 4, GregTechAPI.instance, 64, 3, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("itnt"), ITNTEntity.class, "ITNT", 5, + GregTechAPI.instance, 64, 3, true); } @SideOnly(Side.CLIENT) @@ -32,5 +39,7 @@ public static void initRenderers() { manager -> new DynamiteRenderer(manager, Minecraft.getMinecraft().getRenderItem())); RenderingRegistry.registerEntityRenderingHandler(PortalEntity.class, PortalRenderer::new); RenderingRegistry.registerEntityRenderingHandler(GTBoatEntity.class, GTBoatRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(PowderbarrelEntity.class, GTExplosiveRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(ITNTEntity.class, GTExplosiveRenderer::new); } } diff --git a/src/main/java/gregtech/common/blocks/MetaBlocks.java b/src/main/java/gregtech/common/blocks/MetaBlocks.java index ada71a669ac..1cacda968e6 100644 --- a/src/main/java/gregtech/common/blocks/MetaBlocks.java +++ b/src/main/java/gregtech/common/blocks/MetaBlocks.java @@ -24,6 +24,8 @@ import gregtech.client.renderer.pipe.LaserPipeRenderer; import gregtech.client.renderer.pipe.OpticalPipeRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.explosive.BlockITNT; +import gregtech.common.blocks.explosive.BlockPowderbarrel; import gregtech.common.blocks.foam.BlockFoam; import gregtech.common.blocks.foam.BlockPetrifiedFoam; import gregtech.common.blocks.wood.BlockGregFence; @@ -164,6 +166,8 @@ private MetaBlocks() {} public static BlockFenceGate TREATED_WOOD_FENCE_GATE; public static BlockWoodenDoor RUBBER_WOOD_DOOR; public static BlockWoodenDoor TREATED_WOOD_DOOR; + public static BlockPowderbarrel POWDERBARREL; + public static BlockITNT ITNT; public static BlockBrittleCharcoal BRITTLE_CHARCOAL; @@ -312,6 +316,10 @@ public static void init() { RUBBER_WOOD_DOOR.setRegistryName("rubber_wood_door").setTranslationKey("rubber_wood_door"); TREATED_WOOD_DOOR = new BlockWoodenDoor(() -> MetaItems.TREATED_WOOD_DOOR.getStackForm()); TREATED_WOOD_DOOR.setRegistryName("treated_wood_door").setTranslationKey("treated_wood_door"); + POWDERBARREL = new BlockPowderbarrel(); + POWDERBARREL.setRegistryName("powderbarrel").setTranslationKey("powderbarrel"); + ITNT = new BlockITNT(); + ITNT.setRegistryName("itnt").setTranslationKey("itnt"); BRITTLE_CHARCOAL = new BlockBrittleCharcoal(); BRITTLE_CHARCOAL.setRegistryName("brittle_charcoal"); @@ -481,6 +489,8 @@ public static void registerItemModels() { new ModelResourceLocation(Objects.requireNonNull(TREATED_WOOD_FENCE_GATE.getRegistryName()), "inventory")); registerItemModel(BRITTLE_CHARCOAL); + registerItemModel(POWDERBARREL); + registerItemModel(ITNT); registerItemModel(METAL_SHEET); registerItemModel(LARGE_METAL_SHEET); diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java new file mode 100644 index 00000000000..e18a97abbbf --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java @@ -0,0 +1,175 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Explosion; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@SuppressWarnings("deprecation") +public abstract class BlockGTExplosive extends Block { + + private final boolean canRedstoneActivate; + private final boolean explodeOnMine; + private final int fuseLength; + + /** + * @param canRedstoneActivate whether redstone signal can prime this explosive + * @param explodeOnMine whether mining this block should prime it (sneak mine to drop normally) + * @param fuseLength explosion countdown after priming. Vanilla TNT is 80. + */ + public BlockGTExplosive(Material materialIn, boolean canRedstoneActivate, boolean explodeOnMine, int fuseLength) { + super(materialIn); + this.canRedstoneActivate = canRedstoneActivate; + this.explodeOnMine = explodeOnMine; + this.fuseLength = fuseLength; + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); + } + + protected abstract EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder); + + @Override + public float getExplosionResistance(@NotNull Entity exploder) { + return 1.0f; + } + + @Override + public boolean canBeReplacedByLeaves(@NotNull IBlockState state, @NotNull IBlockAccess world, + @NotNull BlockPos pos) { + return false; + } + + @Override + public boolean isNormalCube(@NotNull IBlockState state) { + return true; + } + + @Override + public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos, + @NotNull EntityLiving.SpawnPlacementType type) { + return false; + } + + @Override + public boolean canDropFromExplosion(@NotNull Explosion explosion) { + return false; + } + + public void explode(World world, BlockPos pos, EntityLivingBase exploder) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, exploder); + entity.setFuse(fuseLength); + world.spawnEntity(entity); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_TNT_PRIMED, + SoundCategory.BLOCKS, 1.0f, 1.0f); + } + } + + @Override + public void onExplosionDestroy(@NotNull World world, @NotNull BlockPos pos, @NotNull Explosion explosion) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, explosion.getExplosivePlacedBy()); + entity.setFuse(world.rand.nextInt(fuseLength / 4) + fuseLength / 8); + world.spawnEntity(entity); + } + } + + @Override + public boolean onBlockActivated(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull EnumFacing facing, + float hitX, float hitY, float hitZ) { + ItemStack stack = player.getHeldItem(hand); + if (!stack.isEmpty() && (stack.getItem() == Items.FLINT_AND_STEEL || stack.getItem() == Items.FIRE_CHARGE)) { + this.explode(world, pos, player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + if (stack.getItem() == Items.FLINT_AND_STEEL) { + stack.damageItem(1, player); + } else if (!player.capabilities.isCreativeMode) { + stack.shrink(1); + } + return true; + } + return super.onBlockActivated(world, pos, state, player, hand, facing, hitX, hitY, hitZ); + } + + @Override + public void dropBlockAsItemWithChance(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + float chance, int fortune) { + if (explodeOnMine) { + EntityPlayer player = this.harvesters.get(); + if (!player.isSneaking()) { + this.explode(world, pos, player); + return; + } + } + super.dropBlockAsItemWithChance(world, pos, state, chance, fortune); + } + + @Override + public void onEntityCollision(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull Entity entity) { + if (!world.isRemote && entity instanceof EntityArrow arrow) { + if (arrow.isBurning()) { + this.explode(world, pos, arrow.shootingEntity instanceof EntityLivingBase living ? living : null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void onBlockAdded(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state) { + super.onBlockAdded(world, pos, state); + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void neighborChanged(@NotNull IBlockState state, @NotNull World world, @NotNull BlockPos pos, + @NotNull Block block, @NotNull BlockPos fromPos) { + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + if (explodeOnMine) { + tooltip.add(I18n.format("tile.gt_explosive.breaking_tooltip")); + } + if (!canRedstoneActivate) { + tooltip.add(I18n.format("tile.gt_explosive.lighting_tooltip")); + } + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java new file mode 100644 index 00000000000..91a9614d4c4 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java @@ -0,0 +1,40 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.ITNTEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockITNT extends BlockGTExplosive { + + public BlockITNT() { + super(Material.TNT, true, true, 40); + setHardness(0); + setSoundType(SoundType.PLANT); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new ITNTEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.itnt.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java new file mode 100644 index 00000000000..a2549ad7ee5 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java @@ -0,0 +1,42 @@ +package gregtech.common.blocks.explosive; + +import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.blocks.material.GTBlockMaterials; +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.PowderbarrelEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockPowderbarrel extends BlockGTExplosive { + + public BlockPowderbarrel() { + super(GTBlockMaterials.POWDERBARREL, false, true, 100); + setHarvestLevel(ToolClasses.AXE, 1); + setHardness(0.5F); + setSoundType(SoundType.WOOD); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new PowderbarrelEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.powderbarrel.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java new file mode 100644 index 00000000000..213ba58fdd9 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java @@ -0,0 +1,18 @@ +package gregtech.common.blocks.material; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; + +public class GTBlockMaterials { + + public static final Material POWDERBARREL = new PowderbarrelMaterial(); + + private static class PowderbarrelMaterial extends Material { + + public PowderbarrelMaterial() { + super(MapColor.STONE); + setAdventureModeExempt(); + setImmovableMobility(); + } + } +} diff --git a/src/main/java/gregtech/common/entities/EntityGTExplosive.java b/src/main/java/gregtech/common/entities/EntityGTExplosive.java new file mode 100644 index 00000000000..70233d7f17b --- /dev/null +++ b/src/main/java/gregtech/common/entities/EntityGTExplosive.java @@ -0,0 +1,136 @@ +package gregtech.common.entities; + +import gregtech.api.util.BlockUtility; +import gregtech.api.util.GregFakePlayer; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.MoverType; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public abstract class EntityGTExplosive extends EntityTNTPrimed { + + public EntityGTExplosive(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public EntityGTExplosive(World world) { + super(world); + } + + /** + * @return The strength of the explosive. + */ + protected abstract float getStrength(); + + /** + * @return Whether to drop all blocks, or use default logic + */ + public abstract boolean dropsAllBlocks(); + + /** + * @return The range of the explosive, if {@link #dropsAllBlocks} is true. + */ + protected int getRange() { + return 2; + } + + /** + * @return The block state of the block this explosion entity is created by. + */ + public abstract @NotNull IBlockState getExplosiveState(); + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + if (!this.hasNoGravity()) { + this.motionY -= 0.03999999910593033D; + } + + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + } + + setFuse(this.getFuse() - 1); + if (this.getFuse() <= 0) { + this.setDead(); + if (!this.world.isRemote) { + this.explodeTNT(); + } + } else { + this.handleWaterMovement(); + this.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, + 0.0D); + } + } + + protected void explodeTNT() { + this.world.createExplosion(this, this.posX, this.posY + (double) (this.height / 16.0F), this.posZ, + getStrength(), !dropsAllBlocks()); + + // If we don't drop all blocks, then skip the drop capture logic + if (!dropsAllBlocks()) return; + + // Create the fake explosion but don't destroy any blocks in water, per MC behavior + if (this.inWater) return; + + EntityPlayer player = GregFakePlayer.get((WorldServer) world); + + int range = getRange(); + for (BlockPos pos : BlockPos.getAllInBox(this.getPosition().add(-range, -range, -range), + this.getPosition().add(range, range, range))) { + IBlockState state = world.getBlockState(pos); + + if (state.getMaterial() == Material.AIR) continue; + if (state.getMaterial() == Material.WATER || state.getMaterial() == Material.LAVA) continue; + + float hardness = state.getBlockHardness(world, pos); + float resistance = state.getBlock().getExplosionResistance(player); + + if (hardness >= 0.0f && resistance < 100 && world.isBlockModifiable(player, pos)) { + List drops = attemptBreakBlockAndObtainDrops(pos, state, player); + + for (ItemStack stack : drops) { + EntityItem entity = new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack); + entity.setDefaultPickupDelay(); + world.spawnEntity(entity); + } + } + } + } + + private List attemptBreakBlockAndObtainDrops(BlockPos pos, IBlockState state, EntityPlayer player) { + if (state.getBlock().removedByPlayer(state, world, pos, player, true)) { + world.playEvent(null, 2001, pos, Block.getStateId(state)); + state.getBlock().onPlayerDestroy(world, pos, state); + + BlockUtility.startCaptureDrops(); + state.getBlock().harvestBlock(world, player, pos, state, world.getTileEntity(pos), ItemStack.EMPTY); + return BlockUtility.stopCaptureDrops(); + } + return Collections.emptyList(); + } +} diff --git a/src/main/java/gregtech/common/entities/ITNTEntity.java b/src/main/java/gregtech/common/entities/ITNTEntity.java new file mode 100644 index 00000000000..3fa60cf4860 --- /dev/null +++ b/src/main/java/gregtech/common/entities/ITNTEntity.java @@ -0,0 +1,41 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class ITNTEntity extends EntityGTExplosive { + + public ITNTEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public ITNTEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 5.0F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + protected int getRange() { + return 3; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.ITNT.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/entities/PowderbarrelEntity.java b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java new file mode 100644 index 00000000000..39f1ed4df56 --- /dev/null +++ b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java @@ -0,0 +1,36 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class PowderbarrelEntity extends EntityGTExplosive { + + public PowderbarrelEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public PowderbarrelEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 3.5F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.POWDERBARREL.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java index 6dd8d6742c7..bdff9524d0d 100644 --- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java @@ -7,6 +7,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; +import gregtech.common.blocks.explosive.BlockGTExplosive; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; @@ -120,8 +121,13 @@ public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull Wo SoundCategory.PLAYERS, 1.0F, GTValues.RNG.nextFloat() * 0.4F + 0.8F); IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); - if (block instanceof BlockTNT) { - ((BlockTNT) block).explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + if (block instanceof BlockTNT tnt) { + tnt.explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + return EnumActionResult.SUCCESS; + } + if (block instanceof BlockGTExplosive powderbarrel) { + powderbarrel.explode(world, pos, player); world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); return EnumActionResult.SUCCESS; } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 97fed7a25c3..269e992be1b 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -5,6 +5,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryModule; @@ -821,8 +822,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), EXPLOSIVE(GTBranchDefinition.GT_INDUSTRIAL, "Explosionis", false, 0x7E270F, 0x747474, beeSpecies -> { - beeSpecies.addProduct(new ItemStack(Blocks.TNT), 0.2f); - // todo if we add a ITNT substitute, put it here instead of TNT + beeSpecies.addProduct(new ItemStack(MetaBlocks.ITNT), 0.2f); beeSpecies.setHumidity(EnumHumidity.ARID); beeSpecies.setTemperature(EnumTemperature.HELLISH); beeSpecies.setHasEffect(); diff --git a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java index 0b0d513a7f7..8b18ba7a811 100644 --- a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java @@ -336,6 +336,11 @@ private static void loadCraftingRecipes() { new UnificationEntry(OrePrefix.wireGtQuadruple, Osmium), 'P', new UnificationEntry(OrePrefix.plateDouble, Iridium), 'O', MetaItems.ENERGY_LAPOTRONIC_ORB.getStackForm()); + + ModHandler.addShapedRecipe("powderbarrel", new ItemStack(MetaBlocks.POWDERBARREL), "PSP", "GGG", "PGP", + 'P', new UnificationEntry(OrePrefix.plate, Wood), + 'S', new ItemStack(Items.STRING), + 'G', new UnificationEntry(OrePrefix.dust, Gunpowder)); } private static void registerFacadeRecipe(Material material, int facadeAmount) { diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java index 7871a518e8c..ebe5ed15505 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java @@ -3,6 +3,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.material.Materials; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import net.minecraft.init.Blocks; @@ -570,6 +571,13 @@ public static void init() { .outputs(new ItemStack(Blocks.TNT)) .duration(200).EUt(24).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() + .inputs(MetaItems.GELLED_TOLUENE.getStackForm(4)) + .fluidInputs(NitrationMixture.getFluid(200)) + .outputs(new ItemStack(MetaBlocks.ITNT)) + .fluidOutputs(DilutedSulfuricAcid.getFluid(150)) + .duration(80).EUt(VA[HV]).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() .input(dust, SodiumHydroxide, 6) .fluidInputs(Dichlorobenzene.getFluid(1000)) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index 74239ff12ae..cbdf94add16 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -13,6 +13,7 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.loaders.recipe.CraftingComponent; @@ -90,14 +91,28 @@ public static void processDust(OrePrefix dustPrefix, Material mat, DustProperty .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesAmount(2) + .explosivesType(new ItemStack(MetaBlocks.POWDERBARREL, 8)) .buildAndRegister(); RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesType(MetaItems.DYNAMITE.getStackForm()) + .explosivesAmount(4) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosivesType(MetaItems.DYNAMITE.getStackForm(2)) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosivesType(new ItemStack(MetaBlocks.ITNT)) .buildAndRegister(); } diff --git a/src/main/resources/assets/gregtech/blockstates/itnt.json b/src/main/resources/assets/gregtech/blockstates/itnt.json new file mode 100644 index 00000000000..79c7d216ccb --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/itnt.json @@ -0,0 +1,16 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_bottom_top", + "textures": { + "bottom": "minecraft:blocks/tnt_bottom", + "top": "minecraft:blocks/tnt_top", + "side": "gregtech:blocks/misc/itnt" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/blockstates/powderbarrel.json b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json new file mode 100644 index 00000000000..60d676619f5 --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_all", + "textures": { + "all": "gregtech:blocks/misc/powderbarrel" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index b102b23fcff..5e2feb89be3 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -2347,6 +2347,17 @@ tile.treated_wood_fence.name=Treated Wood Fence tile.rubber_wood_fence_gate.name=Rubber Wood Fence Gate tile.treated_wood_fence_gate.name=Treated Wood Fence Gate +tile.gt_explosive.breaking_tooltip=Primes explosion when mined, sneak mine to pick back up +tile.gt_explosive.lighting_tooltip=Cannot be lit with Redstone + +tile.powderbarrel.name=Powderbarrel +tile.powderbarrel.drops_tooltip=Slightly larger than TNT, drops all destroyed Blocks as Items +entity.Powderbarrel.name=Powderbarrel + +tile.itnt.name=Industrial TNT +tile.itnt.drops_tooltip=Much larger than TNT, drops all destroyed Blocks as Items +entity.ITNT.name=Industrial TNT + tile.brittle_charcoal.name=Brittle Charcoal tile.brittle_charcoal.tooltip.1=Produced by the Charcoal Pile Igniter. tile.brittle_charcoal.tooltip.2=Mine this to get Charcoal. diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png b/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png new file mode 100644 index 0000000000000000000000000000000000000000..a167e1676b7580be61b14f3826bfb49e4cad4476 GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`vproLLn>}1?|7^9_5YH&KmNZJ zTl9bWY>xlxQ_nL9S!5{xt8eW*@xOCd(|^yW{M^iW_y6%9etvH5@BTCH;>;T_{^Ut$ zYGl-5Sd=KC#&@|vr)?2iq@tPGu0)9(C$9IWD)H zQ&Ty~^1nL`EJf1Q$bayygUG~{_2k1-& MPgg&ebxsLQ0H8ovI{*Lx literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png b/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png new file mode 100644 index 0000000000000000000000000000000000000000..b5624295e93db2bb52a3ccddb55b6ee450b0e7da GIT binary patch literal 243 zcmV Date: Tue, 30 Jan 2024 21:24:47 -0600 Subject: [PATCH 068/168] Refactor other mod id handling (#2354) --- src/main/java/gregtech/api/GTValues.java | 12 +- .../api/block/VariantActiveBlock.java | 5 +- .../api/block/machines/BlockMachine.java | 5 +- .../gregtech/api/fluids/FluidBuilder.java | 5 +- .../api/gui/widgets/SortingButtonWidget.java | 12 +- .../api/items/metaitem/ElectricStats.java | 4 +- .../gregtech/api/items/metaitem/MetaItem.java | 5 +- .../gregtech/api/items/toolitem/IGTTool.java | 24 +- .../api/metatileentity/MetaTileEntity.java | 7 +- .../metatileentity/MetaTileEntityHolder.java | 40 +-- .../java/gregtech/api/recipes/ModHandler.java | 5 +- .../gregtech/api/recipes/RecipeBuilder.java | 13 +- .../java/gregtech/api/recipes/RecipeMap.java | 17 +- .../api/terminal/TerminalRegistry.java | 3 +- .../api/unification/ore/StoneType.java | 5 +- .../java/gregtech/api/util/CapesRegistry.java | 5 +- .../api/util/ModIncompatibilityException.java | 35 +++ src/main/java/gregtech/api/util/Mods.java | 252 ++++++++++++++++++ .../api/worldgen/config/WorldGenRegistry.java | 3 +- .../gregtech/asm/GregTechTransformer.java | 11 +- .../java/gregtech/asm/hooks/CTMHooks.java | 6 +- .../asm/visitors/RenderItemVisitor.java | 4 +- .../java/gregtech/client/ClientProxy.java | 4 +- .../pipeline/VertexLighterFlatSpecial.java | 4 +- .../VertexLighterSmoothAoSpecial.java | 8 +- .../java/gregtech/client/shader/Shaders.java | 32 +-- .../client/utils/BloomEffectUtil.java | 12 +- .../client/utils/DepthTextureUtil.java | 4 +- .../client/utils/ItemRenderCompat.java | 7 +- .../items/behaviors/ColorSprayBehaviour.java | 7 +- .../items/behaviors/ItemMagnetBehavior.java | 4 +- .../metatileentities/MetaTileEntities.java | 6 +- .../electric/MetaTileEntityHull.java | 8 +- .../electric/MetaTileEntityCleanroom.java | 4 +- .../MetaTileEntityCharcoalPileIgniter.java | 3 +- .../widget/WidgetProspectingMap.java | 17 +- .../worldprospector/WorldProspectorARApp.java | 3 +- .../integration/IntegrationModule.java | 6 +- .../gregtech/integration/IntegrationUtil.java | 33 ++- .../integration/baubles/BaublesModule.java | 3 +- .../integration/chisel/ChiselModule.java | 5 +- .../crafttweaker/CraftTweakerModule.java | 3 +- .../material/CTMaterialBuilder.java | 4 +- .../material/MaterialExpansion.java | 8 +- .../integration/ctm/IFacadeWrapper.java | 4 +- .../integration/forestry/ForestryModule.java | 35 ++- .../integration/forestry/ForestryUtil.java | 49 ++-- .../forestry/bees/BeeRemovals.java | 8 +- .../forestry/bees/ForestryScannerLogic.java | 8 +- .../forestry/bees/GTBeeDefinition.java | 105 ++++---- .../integration/forestry/bees/GTCombItem.java | 3 +- .../integration/forestry/bees/GTCombType.java | 8 +- .../integration/forestry/bees/GTDropItem.java | 3 +- .../forestry/frames/GTItemFrame.java | 3 +- .../forestry/recipes/CombRecipes.java | 14 +- .../recipes/ForestryElectrodeRecipes.java | 14 +- .../recipes/ForestryExtractorRecipes.java | 238 ++++++----------- .../forestry/recipes/ForestryMiscRecipes.java | 55 ++-- .../forestry/tools/ScoopBehavior.java | 5 +- .../groovy/GroovyScriptModule.java | 5 +- .../integration/hwyla/HWYLAModule.java | 3 +- .../jei/JustEnoughItemsModule.java | 3 +- .../integration/jei/basic/GTOreInfo.java | 5 +- .../JEIResourceDepositCategoryUtils.java | 6 +- .../opencomputers/OpenComputersModule.java | 9 +- .../theoneprobe/TheOneProbeModule.java | 3 +- .../loaders/recipe/MachineRecipeLoader.java | 4 +- .../MetaTileEntityMachineRecipeLoader.java | 11 +- 68 files changed, 737 insertions(+), 527 deletions(-) create mode 100644 src/main/java/gregtech/api/util/ModIncompatibilityException.java create mode 100644 src/main/java/gregtech/api/util/Mods.java diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 0d57fc6d5f9..05053d6fbb8 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -7,6 +7,8 @@ import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.ApiStatus; + import java.time.LocalDate; import java.util.Random; import java.util.function.Supplier; @@ -120,10 +122,14 @@ public class GTValues { "Overpowered Voltage", "Maximum Voltage" }; /** - * ModID strings, since they are quite common parameters + * GregTech Mod ID */ - public static final String MODID = "gregtech", - MODID_FR = "forestry", + public static final String MODID = "gregtech"; + + /** @deprecated Use {@link gregtech.api.util.Mods} instead */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public static final String MODID_FR = "forestry", MODID_CT = "crafttweaker", MODID_TOP = "theoneprobe", MODID_CTM = "ctm", diff --git a/src/main/java/gregtech/api/block/VariantActiveBlock.java b/src/main/java/gregtech/api/block/VariantActiveBlock.java index 4818c4a933a..ba4ac712a03 100644 --- a/src/main/java/gregtech/api/block/VariantActiveBlock.java +++ b/src/main/java/gregtech/api/block/VariantActiveBlock.java @@ -1,6 +1,6 @@ package gregtech.api.block; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.client.model.ActiveVariantBlockBakedModel; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; @@ -22,7 +22,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -135,7 +134,7 @@ public IExtendedBlockState getExtendedState(@NotNull IBlockState state, @NotNull .withProperty(ACTIVE, Minecraft.getMinecraft().world != null && isBlockActive(Minecraft.getMinecraft().world.provider.getDimension(), pos)); - if (Loader.isModLoaded(GTValues.MODID_CTM)) { + if (Mods.CTM.isModLoaded()) { // if the Connected Textures Mod is loaded we wrap our IExtendedBlockState with their wrapper, // so that the CTM renderer can render the block properly. return new CTMExtendedState(ext, world, pos); diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index d2deda21283..cc2e4dbe3a0 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -1,6 +1,5 @@ package gregtech.api.block.machines; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.BlockCustomParticle; import gregtech.api.block.UnlistedIntegerProperty; @@ -15,6 +14,7 @@ import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pipenet.IBlockAppearance; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.handler.MetaTileEntityRenderer; import gregtech.common.items.MetaItems; import gregtech.integration.ctm.IFacadeWrapper; @@ -55,7 +55,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -281,7 +280,7 @@ public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBloc } } } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (metaTileEntity.getProxy() != null) { metaTileEntity.getProxy().setOwner((EntityPlayer) placer); } diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index f7a75111cc4..a7c9d6528ef 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -1,6 +1,5 @@ package gregtech.api.fluids; -import gregtech.api.GTValues; import gregtech.api.fluids.attribute.AttributedFluid; import gregtech.api.fluids.attribute.FluidAttribute; import gregtech.api.fluids.store.FluidStorageKey; @@ -12,13 +11,13 @@ import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.block.material.MaterialLiquid; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.BlockFluidBase; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import io.github.drmanganese.topaddons.reference.Colors; @@ -380,7 +379,7 @@ private static int convertViscosity(double viscosity) { } // register cross mod compat for colors - if (Loader.isModLoaded(GTValues.MODID_TOP_ADDONS)) { + if (Mods.TOPAddons.isModLoaded()) { int displayColor = isColorEnabled || material == null ? color : material.getMaterialRGB(); Colors.FLUID_NAME_COLOR_MAP.put(name, displayColor); } diff --git a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java index d053c49e7d1..2c491d18ecc 100644 --- a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java @@ -1,14 +1,13 @@ package gregtech.api.gui.widgets; +import gregtech.api.util.Mods; + import net.minecraft.client.settings.KeyBinding; -import net.minecraftforge.fml.common.Loader; import java.util.function.Consumer; public class SortingButtonWidget extends ClickButtonWidget { - private static boolean inventoryTweaksChecked; - private static boolean inventoryTweaksPresent; private static KeyBinding sortKeyBinding; public SortingButtonWidget(int xPosition, int yPosition, int width, int height, String displayText, @@ -43,13 +42,10 @@ public boolean keyTyped(char charTyped, int keyCode) { } private static int getInvTweaksSortCode() { - if (!inventoryTweaksChecked) { - inventoryTweaksChecked = true; - inventoryTweaksPresent = Loader.isModLoaded("inventorytweaks"); - } - if (!inventoryTweaksPresent) { + if (!Mods.InventoryTweaks.isModLoaded()) { return 0; } + try { if (sortKeyBinding == null) { Class proxyClass = Class.forName("invtweaks.forge.ClientProxy"); diff --git a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java index 91bd1b739da..bf336ec4676 100644 --- a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java +++ b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java @@ -6,6 +6,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.capability.impl.ElectricItem; import gregtech.api.items.metaitem.stats.*; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.baubles.BaublesModule; @@ -25,7 +26,6 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; -import net.minecraftforge.fml.common.Loader; import java.time.Duration; import java.time.Instant; @@ -75,7 +75,7 @@ public void onUpdate(ItemStack itemStack, Entity entity) { IInventory inventoryPlayer = entityPlayer.inventory; long transferLimit = electricItem.getTransferLimit(); - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventoryPlayer = BaublesModule.getBaublesWrappedInventory(entityPlayer); } diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index c0dac9c52fd..595e3e0a9fc 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -20,6 +20,7 @@ import gregtech.api.unification.stack.ItemMaterialInfo; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.common.ConfigHolder; @@ -94,7 +95,9 @@ * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } This will add single-use (not * rechargeable) LV battery with initial capacity 10000 EU */ -@Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") +@Optional.Interface( + modid = Mods.Names.ENDER_CORE, + iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item implements ItemUIFactory, IOverlayRenderAware { diff --git a/src/main/java/gregtech/api/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 4c3ba369341..94ae45effb9 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -24,6 +24,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.client.utils.TooltipHelper; @@ -89,14 +90,21 @@ * Backing of every variation of a GT Tool */ @Optional.InterfaceList({ - @Optional.Interface(modid = GTValues.MODID_APPENG, iface = "appeng.api.implementations.items.IAEWrench"), - @Optional.Interface(modid = GTValues.MODID_BC, iface = "buildcraft.api.tools.IToolWrench"), - @Optional.Interface(modid = GTValues.MODID_COFH, iface = "cofh.api.item.IToolHammer"), - @Optional.Interface(modid = GTValues.MODID_EIO, iface = "crazypants.enderio.api.tool.ITool"), - @Optional.Interface(modid = GTValues.MODID_FR, iface = "forestry.api.arboriculture.IToolGrafter"), - @Optional.Interface(modid = GTValues.MODID_PROJRED_CORE, iface = "mrtjp.projectred.api.IScrewdriver"), - @Optional.Interface(modid = GTValues.MODID_RC, iface = "mods.railcraft.api.items.IToolCrowbar"), - @Optional.Interface(modid = GTValues.MODID_ECORE, + @Optional.Interface(modid = Mods.Names.APPLIED_ENERGISTICS2, + iface = "appeng.api.implementations.items.IAEWrench"), + @Optional.Interface(modid = Mods.Names.BUILD_CRAFT_CORE, + iface = "buildcraft.api.tools.IToolWrench"), + @Optional.Interface(modid = Mods.Names.COFH_CORE, + iface = "cofh.api.item.IToolHammer"), + @Optional.Interface(modid = Mods.Names.ENDER_IO, + iface = "crazypants.enderio.api.tool.ITool"), + @Optional.Interface(modid = Mods.Names.FORESTRY, + iface = "forestry.api.arboriculture.IToolGrafter"), + @Optional.Interface(modid = Mods.Names.PROJECT_RED_CORE, + iface = "mrtjp.projectred.api.IScrewdriver"), + @Optional.Interface(modid = Mods.Names.RAILCRAFT, + iface = "mods.railcraft.api.items.IToolCrowbar"), + @Optional.Interface(modid = Mods.Names.ENDER_CORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") }) public interface IGTTool extends ItemUIFactory, IAEWrench, IToolWrench, IToolHammer, ITool, IToolGrafter, IOverlayRenderAware, IScrewdriver, IToolCrowbar { diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 1412a674817..b29f8485b00 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -19,6 +19,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; @@ -1491,17 +1492,17 @@ public boolean canVoidRecipeFluidOutputs() { } @NotNull - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.NONE; } @Nullable - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return null; } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() {} } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 9d5662a1153..5c6487e6180 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -1,6 +1,5 @@ package gregtech.api.metatileentity; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.machines.BlockMachine; import gregtech.api.capability.GregtechDataCodes; @@ -8,6 +7,7 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.particle.GTNameTagParticle; import gregtech.client.particle.GTParticleManager; @@ -29,7 +29,6 @@ import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional.Interface; import net.minecraftforge.fml.common.Optional.InterfaceList; import net.minecraftforge.fml.common.Optional.Method; @@ -54,10 +53,11 @@ @InterfaceList(value = { @Interface(iface = "appeng.api.networking.security.IActionHost", - modid = GTValues.MODID_APPENG, + modid = Mods.Names.APPLIED_ENERGISTICS2, striprefs = true), - @Interface(iface = "appeng.me.helpers.IGridProxyable", modid = GTValues.MODID_APPENG, striprefs = true), -}) + @Interface(iface = "appeng.me.helpers.IGridProxyable", + modid = Mods.Names.APPLIED_ENERGISTICS2, + striprefs = true) }) public class MetaTileEntityHolder extends TickableTileEntityBase implements IGregTechTileEntity, IUIHolder, IWorldNameable, IActionHost, IGridProxyable { @@ -138,7 +138,7 @@ public void readFromNBT(@NotNull NBTTagCompound compound) { } else { GTLog.logger.error("Failed to load MetaTileEntity with invalid ID " + metaTileEntityIdRaw); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { readFromNBT_AENetwork(compound); } } @@ -154,7 +154,7 @@ public NBTTagCompound writeToNBT(@NotNull NBTTagCompound compound) { NBTTagCompound metaTileEntityData = new NBTTagCompound(); metaTileEntity.writeToNBT(metaTileEntityData); compound.setTag("MetaTileEntity", metaTileEntityData); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { writeToNBT_AENetwork(compound); } } @@ -167,7 +167,7 @@ public void invalidate() { metaTileEntity.invalidate(); } super.invalidate(); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { invalidateAE(); } } @@ -375,7 +375,7 @@ public void onChunkUnload() { if (metaTileEntity != null) { metaTileEntity.onUnload(); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { onChunkUnloadAE(); } } @@ -505,7 +505,7 @@ public ITextComponent getDisplayName() { @Nullable @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getGridNode(@NotNull AEPartLocation part) { // Forbid it connects the faces it shouldn't connect. if (this.getCableConnectionType(part) == AECableType.NONE) { @@ -517,44 +517,44 @@ public IGridNode getGridNode(@NotNull AEPartLocation part) { @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return metaTileEntity == null ? AECableType.NONE : metaTileEntity.getCableConnectionType(part); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void securityBreak() {} @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getActionableNode() { AENetworkProxy proxy = getProxy(); return proxy == null ? null : proxy.getNode(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return metaTileEntity == null ? null : metaTileEntity.getProxy(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public DimensionalCoord getLocation() { return new DimensionalCoord(this); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() { if (metaTileEntity != null) { metaTileEntity.gridChanged(); } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void readFromNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -562,7 +562,7 @@ public void readFromNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void writeToNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -570,7 +570,7 @@ public void writeToNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void onChunkUnloadAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -578,7 +578,7 @@ void onChunkUnloadAE() { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void invalidateAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { diff --git a/src/main/java/gregtech/api/recipes/ModHandler.java b/src/main/java/gregtech/api/recipes/ModHandler.java index 010d1c22346..1fe7ce05f07 100644 --- a/src/main/java/gregtech/api/recipes/ModHandler.java +++ b/src/main/java/gregtech/api/recipes/ModHandler.java @@ -16,6 +16,7 @@ import gregtech.api.util.DummyContainer; import gregtech.api.util.GTLog; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.world.DummyWorld; import gregtech.common.ConfigHolder; import gregtech.common.crafting.FluidReplaceRecipe; @@ -679,8 +680,6 @@ public static Pair getRecipeOutput(@Nullable World world, @N * disable the config and remove the recipes manually */ public static void removeSmeltingEBFMetals() { - boolean isCTLoaded = Loader.isModLoaded(GTValues.MODID_CT); - Field actionAddFurnaceRecipe$output = null; Map furnaceList = FurnaceRecipes.instance().getSmeltingList(); @@ -702,7 +701,7 @@ public static void removeSmeltingEBFMetals() { ItemStack ingot = OreDictUnifier.get(OrePrefix.ingot, material); // Check if the inputs are actually dust -> ingot if (ingot.isItemEqual(output) && dust.isItemEqual(input)) { - if (isCTLoaded) { + if (Mods.CraftTweaker.isModLoaded()) { if (actionAddFurnaceRecipe$output == null) { try { actionAddFurnaceRecipe$output = ActionAddFurnaceRecipe.class diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index dd5fee598df..87175224c5d 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -22,6 +22,7 @@ import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.groovy.GroovyScriptModule; @@ -607,12 +608,12 @@ public R chancedFluidOutputLogic(@NotNull ChancedOutputLogic logic) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient ingredient) { return input(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient... ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -620,7 +621,7 @@ public R inputs(IIngredient... ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(Collection ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -628,12 +629,12 @@ public R inputs(Collection ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R notConsumable(IIngredient ingredient) { return notConsumable(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) private static GTRecipeInput ofGroovyIngredient(IIngredient ingredient) { if (ingredient instanceof OreDictIngredient) { return new GTRecipeOreInput(((OreDictIngredient) ingredient).getOreDict(), ingredient.getAmount()); @@ -857,7 +858,7 @@ protected EnumValidationResult validate() { return recipeStatus; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) protected void validateGroovy(GroovyLog.Msg errorMsg) { errorMsg.add(EUt == 0, () -> "EU/t must not be to 0"); errorMsg.add(duration <= 0, () -> "Duration must not be less or equal to 0"); diff --git a/src/main/java/gregtech/api/recipes/RecipeMap.java b/src/main/java/gregtech/api/recipes/RecipeMap.java index c73fc20bb74..4c48707b5f3 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMap.java +++ b/src/main/java/gregtech/api/recipes/RecipeMap.java @@ -18,7 +18,12 @@ import gregtech.api.recipes.map.*; import gregtech.api.unification.material.Material; import gregtech.api.unification.ore.OrePrefix; -import gregtech.api.util.*; +import gregtech.api.util.EnumValidationResult; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTUtility; +import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; +import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.crafttweaker.CTRecipeHelper; import gregtech.integration.crafttweaker.recipe.CTRecipe; @@ -940,7 +945,7 @@ private boolean shouldShiftWidgets() { getMaxFluidInputs() + getMaxFluidOutputs() >= 6; } - @Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Method(modid = Mods.Names.GROOVY_SCRIPT) private VirtualizedRecipeMap getGroovyScriptRecipeMap() { return ((VirtualizedRecipeMap) grsVirtualizedRecipeMap); } @@ -1282,7 +1287,7 @@ public SoundEvent getSound() { } @ZenMethod("findRecipe") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) @Nullable public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidStack[] fluidInputs, @Optional(valueLong = Integer.MAX_VALUE) int outputFluidTankCapacity) { @@ -1295,8 +1300,8 @@ public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidSt } @ZenGetter("recipes") - @Method(modid = GTValues.MODID_CT) - public List ccGetRecipeList() { + @Method(modid = Mods.Names.CRAFT_TWEAKER) + public List ctGetRecipeList() { return getRecipeList().stream().map(recipe -> new CTRecipe(this, recipe)).collect(Collectors.toList()); } @@ -1385,7 +1390,7 @@ private Recipe recurseIngredientTreeRemove(@NotNull Recipe recipeToRemove, } @ZenMethod("recipeBuilder") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public CTRecipeBuilder ctRecipeBuilder() { return new CTRecipeBuilder(recipeBuilder()); } diff --git a/src/main/java/gregtech/api/terminal/TerminalRegistry.java b/src/main/java/gregtech/api/terminal/TerminalRegistry.java index 6da73912e23..e842eb0c7a9 100644 --- a/src/main/java/gregtech/api/terminal/TerminalRegistry.java +++ b/src/main/java/gregtech/api/terminal/TerminalRegistry.java @@ -5,6 +5,7 @@ import gregtech.api.terminal.hardware.Hardware; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; import gregtech.common.terminal.app.VirtualTankApp; @@ -131,7 +132,7 @@ public static void init() { .upgrade(1, MetaItems.EMITTER_HV.getStackForm(4), MetaItems.WORKSTATION_EV.getStackForm(2)) .defaultApp() .build(); - if (Loader.isModLoaded(GTValues.MODID_JEI)) { + if (Mods.JustEnoughItems.isModLoaded()) { AppRegistryBuilder.create(new RecipeChartApp()) .battery(GTValues.LV, 160) .upgrade(0, new ItemStack(Items.PAPER, 32)) diff --git a/src/main/java/gregtech/api/unification/ore/StoneType.java b/src/main/java/gregtech/api/unification/ore/StoneType.java index f92bb9c68bf..9e87a43a0b8 100644 --- a/src/main/java/gregtech/api/unification/ore/StoneType.java +++ b/src/main/java/gregtech/api/unification/ore/StoneType.java @@ -1,9 +1,9 @@ package gregtech.api.unification.ore; -import gregtech.api.GTValues; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.util.GTControlledRegistry; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.jei.basic.OreByProduct; @@ -11,7 +11,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import org.jetbrains.annotations.NotNull; @@ -50,7 +49,7 @@ public StoneType(int id, String name, SoundType soundType, OrePrefix processingP this.predicate = predicate::test; this.shouldBeDroppedAsItem = shouldBeDroppedAsItem || ConfigHolder.worldgen.allUniqueStoneTypes; STONE_TYPE_REGISTRY.register(id, name, this); - if (Loader.isModLoaded(GTValues.MODID_JEI) && this.shouldBeDroppedAsItem) { + if (Mods.JustEnoughItems.isModLoaded() && this.shouldBeDroppedAsItem) { OreByProduct.addOreByProductPrefix(this.processingPrefix); } } diff --git a/src/main/java/gregtech/api/util/CapesRegistry.java b/src/main/java/gregtech/api/util/CapesRegistry.java index 50972a56236..7d0acaa0ba6 100644 --- a/src/main/java/gregtech/api/util/CapesRegistry.java +++ b/src/main/java/gregtech/api/util/CapesRegistry.java @@ -1,6 +1,5 @@ package gregtech.api.util; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.client.renderer.texture.Textures; import gregtech.core.network.packets.PacketNotifyCapeChange; @@ -214,13 +213,13 @@ public static void addFreeCape(ResourceLocation cape) { private static final List> ctRegisterCapes = new ArrayList<>(); private static final List ctFreeCapes = new ArrayList<>(); - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerCape(String advancement, String cape) { ctRegisterCapes.add(new Tuple<>(new ResourceLocation(advancement), new ResourceLocation(cape))); } - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerFreeCape(String cape) { ctFreeCapes.add(new ResourceLocation(cape)); diff --git a/src/main/java/gregtech/api/util/ModIncompatibilityException.java b/src/main/java/gregtech/api/util/ModIncompatibilityException.java new file mode 100644 index 00000000000..c21439cc5fe --- /dev/null +++ b/src/main/java/gregtech/api/util/ModIncompatibilityException.java @@ -0,0 +1,35 @@ +package gregtech.api.util; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiErrorScreen; +import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; + +@SideOnly(Side.CLIENT) +public class ModIncompatibilityException extends CustomModLoadingErrorDisplayException { + + @SuppressWarnings("all") + private static final long serialVersionUID = 1L; + + private final List messages; + + public ModIncompatibilityException(List messages) { + this.messages = messages; + } + + @Override + public void initGui(GuiErrorScreen guiErrorScreen, FontRenderer fontRenderer) {} + + @Override + public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseX, int mouseY, float time) { + int x = errorScreen.width / 2; + int y = 75; + for (String message : messages) { + errorScreen.drawCenteredString(fontRenderer, message, x, y, 0xFFFFFF); + y += 15; + } + } +} diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java new file mode 100644 index 00000000000..c022672f095 --- /dev/null +++ b/src/main/java/gregtech/api/util/Mods.java @@ -0,0 +1,252 @@ +package gregtech.api.util; + +import gregtech.api.GTValues; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +public enum Mods { + + AdvancedRocketry(Names.ADVANCED_ROCKETRY), + AppliedEnergistics2(Names.APPLIED_ENERGISTICS2), + Baubles(Names.BAUBLES), + BinnieCore(Names.BINNIE_CORE), + BiomesOPlenty(Names.BIOMES_O_PLENTY), + BuildCraftCore(Names.BUILD_CRAFT_CORE), + Chisel(Names.CHISEL), + CoFHCore(Names.COFH_CORE), + CTM(Names.CONNECTED_TEXTURES_MOD), + CubicChunks(Names.CUBIC_CHUNKS), + CraftTweaker(Names.CRAFT_TWEAKER), + EnderCore(Names.ENDER_CORE), + EnderIO(Names.ENDER_IO), + ExtraBees(Names.EXTRA_BEES), + ExtraTrees(Names.EXTRA_TREES), + ExtraUtilities2(Names.EXTRA_UTILITIES2), + Forestry(Names.FORESTRY), + ForestryApiculture(Names.FORESTRY, forestryModule(Names.FORESTRY_APICULTURE)), + ForestryArboriculture(Names.FORESTRY, forestryModule(Names.FORESTRY_ARBORICULTURE)), + ForestryLepidopterology(Names.FORESTRY, forestryModule(Names.FORESTRY_LEPIDOPTEROLOGY)), + GalacticraftCore(Names.GALACTICRAFT_CORE), + Genetics(Names.GENETICS), + GregTech(Names.GREGTECH), + GregTechFoodOption(Names.GREGTECH_FOOD_OPTION), + GroovyScript(Names.GROOVY_SCRIPT), + GTCE2OC(Names.GTCE_2_OC), + HWYLA(Names.HWYLA), + ImmersiveEngineering(Names.IMMERSIVE_ENGINEERING), + IndustrialCraft2(Names.INDUSTRIAL_CRAFT2), + InventoryTweaks(Names.INVENTORY_TWEAKS), + JourneyMap(Names.JOURNEY_MAP), + JustEnoughItems(Names.JUST_ENOUGH_ITEMS), + MagicBees(Names.MAGIC_BEES), + Nothirium(Names.NOTHIRIUM), + NuclearCraft(Names.NUCLEAR_CRAFT, versionExcludes("2o")), + NuclearCraftOverhauled(Names.NUCLEAR_CRAFT, versionContains("2o")), + OpenComputers(Names.OPEN_COMPUTERS), + ProjectRedCore(Names.PROJECT_RED_CORE), + Railcraft(Names.RAILCRAFT), + RefinedStorage(Names.REFINED_STORAGE), + TechReborn(Names.TECH_REBORN), + TheOneProbe(Names.THE_ONE_PROBE), + TinkersConstruct(Names.TINKERS_CONSTRUCT), + TOPAddons(Names.TOP_ADDONS), + VoxelMap(Names.VOXEL_MAP), + XaerosMinimap(Names.XAEROS_MINIMAP), + + // Special Optifine handler, but consolidated here for simplicity + Optifine(null) { + + @Override + public boolean isModLoaded() { + if (this.modLoaded == null) { + try { + Class c = Class.forName("net.optifine.shaders.Shaders"); + Field f = c.getDeclaredField("shaderPackLoaded"); + f.setAccessible(true); + this.modLoaded = f.getBoolean(null); + } catch (Exception ignored) { + this.modLoaded = false; + } + } + return this.modLoaded; + } + }; + + public static class Names { + + public static final String ADVANCED_ROCKETRY = "advancedrocketry"; + public static final String APPLIED_ENERGISTICS2 = "appliedenergistics2"; + public static final String BAUBLES = "baubles"; + public static final String BINNIE_CORE = "binniecore"; + public static final String BIOMES_O_PLENTY = "biomesoplenty"; + public static final String BUILD_CRAFT_CORE = "buildcraftcore"; + public static final String CHISEL = "chisel"; + public static final String COFH_CORE = "cofhcore"; + public static final String CONNECTED_TEXTURES_MOD = "ctm"; + public static final String CUBIC_CHUNKS = "cubicchunks"; + public static final String CRAFT_TWEAKER = "crafttweaker"; + public static final String ENDER_CORE = "endercore"; + public static final String ENDER_IO = "enderio"; + public static final String EXTRA_BEES = "extrabees"; + public static final String EXTRA_TREES = "extratrees"; + public static final String EXTRA_UTILITIES2 = "extrautils2"; + public static final String FORESTRY = "forestry"; + public static final String FORESTRY_APICULTURE = "apiculture"; + public static final String FORESTRY_ARBORICULTURE = "arboriculture"; + public static final String FORESTRY_LEPIDOPTEROLOGY = "lepidopterology"; + public static final String GALACTICRAFT_CORE = "galacticraftcore"; + public static final String GENETICS = "genetics"; + public static final String GREGTECH = GTValues.MODID; + public static final String GREGTECH_FOOD_OPTION = "gregtechfoodoption"; + public static final String GROOVY_SCRIPT = "groovyscript"; + public static final String GTCE_2_OC = "gtce2oc"; + public static final String HWYLA = "hwyla"; + public static final String IMMERSIVE_ENGINEERING = "immersiveengineering"; + public static final String INDUSTRIAL_CRAFT2 = "ic2"; + public static final String INVENTORY_TWEAKS = "inventorytweaks"; + public static final String JOURNEY_MAP = "journeymap"; + public static final String JUST_ENOUGH_ITEMS = "jei"; + public static final String MAGIC_BEES = "magicbees"; + public static final String NOTHIRIUM = "nothirium"; + public static final String NUCLEAR_CRAFT = "nuclearcraft"; + public static final String OPEN_COMPUTERS = "opencomputers"; + public static final String PROJECT_RED_CORE = "projred-core"; + public static final String RAILCRAFT = "railcraft"; + public static final String REFINED_STORAGE = "refinedstorage"; + public static final String TECH_REBORN = "techreborn"; + public static final String THE_ONE_PROBE = "theoneprobe"; + public static final String TINKERS_CONSTRUCT = "tconstruct"; + public static final String TOP_ADDONS = "topaddons"; + public static final String VOXEL_MAP = "voxelmap"; + public static final String XAEROS_MINIMAP = "xaerominimap"; + } + + private final String ID; + private final Function extraCheck; + protected Boolean modLoaded; + + Mods(String ID) { + this.ID = ID; + this.extraCheck = null; + } + + /** + * @param extraCheck A supplier that can be used to test additional factors, such as + * checking if a mod is at a specific version, or a sub-mod is loaded. + * Used in cases like NC vs NCO, where the mod id is the same + * so the version has to be parsed to test which is loaded. + * Another case is checking for specific Forestry modules, checking + * if Forestry is loaded and if a specific module is enabled. + */ + Mods(String ID, Function extraCheck) { + this.ID = ID; + this.extraCheck = extraCheck; + } + + public boolean isModLoaded() { + if (this.modLoaded == null) { + this.modLoaded = Loader.isModLoaded(this.ID); + if (this.modLoaded) { + if (this.extraCheck != null && !this.extraCheck.apply(this)) { + this.modLoaded = false; + } + } + } + return this.modLoaded; + } + + /** + * Throw an exception if this mod is found to be loaded. + * This must be called in or after + * {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent}! + */ + public void throwIncompatibilityIfLoaded(String... customMessages) { + if (isModLoaded()) { + String modName = TextFormatting.BOLD + ID + TextFormatting.RESET; + List messages = new ArrayList<>(); + messages.add(modName + " mod detected, this mod is incompatible with GregTech CE Unofficial."); + messages.addAll(Arrays.asList(customMessages)); + if (FMLLaunchHandler.side() == Side.SERVER) { + throw new RuntimeException(String.join(",", messages)); + } else { + throwClientIncompatibility(messages); + } + } + } + + @SideOnly(Side.CLIENT) + private static void throwClientIncompatibility(List messages) { + throw new ModIncompatibilityException(messages); + } + + public ItemStack getItem(@NotNull String name) { + return getItem(name, 0, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta) { + return getItem(name, meta, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount) { + return getItem(name, meta, amount, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount, @Nullable String nbt) { + if (!isModLoaded()) { + return ItemStack.EMPTY; + } + return GameRegistry.makeItemStack(ID + ":" + name, meta, amount, nbt); + } + + // Helpers for the extra checker + + /** Test if the mod version string contains the passed value. */ + private static Function versionContains(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return container.getVersion().contains(versionPart); + }; + } + + /** Test if the mod version string does not contain the passed value. */ + private static Function versionExcludes(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return !container.getVersion().contains(versionPart); + }; + } + + /** Test if a specific Forestry module is enabled. */ + private static Function forestryModule(String moduleID) { + if (Forestry.isModLoaded()) { + return mod -> forestry.modules.ModuleHelper.isEnabled(moduleID); + } else { + return $ -> false; + } + } +} diff --git a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java index 2a30f9e1eeb..858f28bc328 100644 --- a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java +++ b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.filler.BlacklistedBlockFiller; import gregtech.api.worldgen.filler.BlockFiller; import gregtech.api.worldgen.filler.LayeredBlockFiller; @@ -123,7 +124,7 @@ public void initializeRegistry() { } catch (IOException | RuntimeException exception) { GTLog.logger.fatal("Failed to initialize worldgen registry.", exception); } - if (Loader.isModLoaded("galacticraftcore")) { + if (Mods.GalacticraftCore.isModLoaded()) { try { Class transformerHooksClass = Class.forName("micdoodle8.mods.galacticraft.core.TransformerHooks"); Field otherModGeneratorsWhitelistField = transformerHooksClass diff --git a/src/main/java/gregtech/asm/GregTechTransformer.java b/src/main/java/gregtech/asm/GregTechTransformer.java index 4d98621cfa8..005ec295075 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -1,6 +1,6 @@ package gregtech.asm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import gregtech.asm.util.TargetClassVisitor; import gregtech.asm.visitors.*; @@ -8,8 +8,6 @@ import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.ModContainer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; @@ -136,13 +134,12 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) ClassReader classReader = new ClassReader(basicClass); ClassWriter classWriter = new ClassWriter(0); - // fix NC recipe compat different depending on overhaul vs underhaul - ModContainer container = Loader.instance().getIndexedModList().get(GTValues.MODID_NC); - if (container.getVersion().contains("2o")) { // overhauled + // fix NC recipe compat different depending on overhaul vs normal + if (Mods.NuclearCraftOverhauled.isModLoaded()) { classReader.accept(new TargetClassVisitor(classWriter, NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NCO, NuclearCraftRecipeHelperVisitor::new), 0); - } else { + } else if (Mods.NuclearCraft.isModLoaded()) { classReader.accept(new TargetClassVisitor(classWriter, NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NC, NuclearCraftRecipeHelperVisitor::new), 0); } diff --git a/src/main/java/gregtech/asm/hooks/CTMHooks.java b/src/main/java/gregtech/asm/hooks/CTMHooks.java index eaf4f7ad51c..bf254934d5c 100644 --- a/src/main/java/gregtech/asm/hooks/CTMHooks.java +++ b/src/main/java/gregtech/asm/hooks/CTMHooks.java @@ -1,6 +1,6 @@ package gregtech.asm.hooks; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.client.utils.BloomEffectUtil; import net.minecraft.block.state.IBlockState; @@ -20,7 +20,7 @@ public class CTMHooks { public static ThreadLocal ENABLE = new ThreadLocal<>(); public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte layers, BlockRenderLayer layer) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { if (canRenderInLayer) { if (layer == BloomEffectUtil.getBloomLayer()) return false; } else if ((layers >> BloomEffectUtil.getBloomLayer().ordinal() & 1) == 1 && @@ -34,7 +34,7 @@ public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte laye public static List getQuadsWithOptiFine(List ret, BlockRenderLayer layer, IBakedModel bakedModel, IBlockState state, EnumFacing side, long rand) { - if (Shaders.isOptiFineShaderPackLoaded() && CTMHooks.ENABLE.get() == null) { + if (Mods.Optifine.isModLoaded() && CTMHooks.ENABLE.get() == null) { if (layer == BloomEffectUtil.getBloomLayer()) { return Collections.emptyList(); } else if (layer == BloomEffectUtil.getEffectiveBloomLayer()) { diff --git a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java index f1b87a1fc12..750de53af3b 100644 --- a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java +++ b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java @@ -1,6 +1,6 @@ package gregtech.asm.visitors; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import net.minecraftforge.fml.common.Loader; @@ -28,7 +28,7 @@ public static void transform(Iterator methods) { callRenderLampOverlay.add(new MethodInsnNode(INVOKESTATIC, "gregtech/asm/hooks/RenderItemHooks", "renderLampOverlay", "(Lnet/minecraft/item/ItemStack;II)V", false)); - boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(GTValues.MODID_ECORE); + boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(Mods.Names.ENDER_CORE); // do not conflict with EnderCore's changes, which already do what we need InsnList callRenderElectricBar; diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 2b7207a232d..7fb4773d478 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -10,6 +10,7 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.IBlockOre; +import gregtech.api.util.Mods; import gregtech.client.model.customtexture.CustomTextureModelHandler; import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; @@ -52,7 +53,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -77,7 +77,7 @@ public void onPreLoad() { SoundSystemConfig.setNumberNormalChannels(ConfigHolder.client.maxNumSounds); - if (!Loader.isModLoaded(GTValues.MODID_CTM)) { + if (!Mods.CTM.isModLoaded()) { Minecraft.getMinecraft().metadataSerializer.registerMetadataSectionType(new MetadataSectionCTM.Serializer(), MetadataSectionCTM.class); MinecraftForge.EVENT_BUS.register(CustomTextureModelHandler.INSTANCE); diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java index 75f05440797..9f8580344ec 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.client.renderer.vertex.VertexFormat; @@ -134,7 +134,7 @@ protected void processQuad() { updateColor(normal[v], color[v], x, y, z, tint, multiplier); // When enabled this causes the rendering to be black with Optifine - if (!Shaders.isOptiFineShaderPackLoaded() && diffuse) { + if (!Mods.Optifine.isModLoaded() && diffuse) { float d = LightUtil.diffuseLight(normal[v][0], normal[v][1], normal[v][2]); for (int i = 0; i < 3; i++) { color[v][i] *= d; diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java index 79b83e9998e..f1d6f852e3c 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.util.math.MathHelper; @@ -15,7 +15,7 @@ public VertexLighterSmoothAoSpecial(BlockColors colors) { @Override protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateLightmap(normal, lightmap, x, y, z); return; } @@ -28,7 +28,7 @@ protected void updateLightmap(float[] normal, float[] lightmap, float x, float y protected void updateColor(float[] normal, float[] color, float x, float y, float z, float tint, int multiplier) { super.updateColor(normal, color, x, y, z, tint, multiplier); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return; } @@ -146,7 +146,7 @@ protected float getAo(float x, float y, float z) { @Override public void updateBlockInfo() { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateBlockInfo(); return; } diff --git a/src/main/java/gregtech/client/shader/Shaders.java b/src/main/java/gregtech/client/shader/Shaders.java index e1eb6ef0474..1d20438bbbb 100644 --- a/src/main/java/gregtech/client/shader/Shaders.java +++ b/src/main/java/gregtech/client/shader/Shaders.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -15,11 +16,10 @@ import codechicken.lib.render.shader.ShaderObject; import codechicken.lib.render.shader.ShaderProgram; +import org.jetbrains.annotations.ApiStatus; -import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; import static codechicken.lib.render.shader.ShaderHelper.getStream; @@ -57,35 +57,12 @@ public class Shaders { public static ShaderObject S_BLUR; public static ShaderObject COMPOSITE; - // OptiFine - private static BooleanSupplier isShaderPackLoaded; - static { mc = Minecraft.getMinecraft(); FULL_IMAGE_PROGRAMS = new HashMap<>(); if (allowedShader()) { initShaders(); } - try { // hook optFine. thanks to Scannable. - final Class clazz = Class.forName("net.optifine.shaders.Shaders"); - final Field shaderPackLoaded = clazz.getDeclaredField("shaderPackLoaded"); - shaderPackLoaded.setAccessible(true); - isShaderPackLoaded = () -> { - try { - return shaderPackLoaded.getBoolean(null); - } catch (final IllegalAccessException e) { - GTLog.logger.warn( - "Failed reading field indicating whether shaders are enabled. Shader mod integration disabled."); - isShaderPackLoaded = null; - return false; - } - }; - GTLog.logger.info("Find optiFine mod loaded."); - } catch (ClassNotFoundException e) { - GTLog.logger.info("No optiFine mod found."); - } catch (NoSuchFieldException | NoClassDefFoundError e) { - GTLog.logger.warn("Failed integrating with shader mod. Ignoring."); - } } public static void initShaders() { @@ -128,8 +105,11 @@ public static boolean allowedShader() { return OpenGlHelper.shadersSupported && ConfigHolder.client.shader.useShader; } + /** @deprecated Use {@link Mods#Optifine} to check this instead. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static boolean isOptiFineShaderPackLoaded() { - return isShaderPackLoaded != null && isShaderPackLoaded.getAsBoolean(); + return Mods.Optifine.isModLoaded(); } public static Framebuffer renderFullImageInFBO(Framebuffer fbo, ShaderObject frag, diff --git a/src/main/java/gregtech/client/utils/BloomEffectUtil.java b/src/main/java/gregtech/client/utils/BloomEffectUtil.java index d1ac6f07cc0..2dcc7d0be14 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectUtil.java @@ -1,6 +1,7 @@ package gregtech.client.utils; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.Mods; import gregtech.client.particle.GTParticle; import gregtech.client.renderer.IRenderSetup; import gregtech.client.shader.Shaders; @@ -20,7 +21,6 @@ import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockRenderLayer; import net.minecraftforge.common.util.EnumHelper; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -101,7 +101,7 @@ public static BlockRenderLayer getEffectiveBloomLayer() { */ @Contract("null -> _; !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() ? fallback : bloom; + return Mods.Optifine.isModLoaded() ? fallback : bloom; } /** @@ -133,7 +133,7 @@ public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive) { */ @Contract("_, null -> _; _, !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive, BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() || !isBloomActive ? fallback : bloom; + return Mods.Optifine.isModLoaded() || !isBloomActive ? fallback : bloom; } /** @@ -221,7 +221,7 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup @NotNull BloomType bloomType, @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { - if (Shaders.isOptiFineShaderPackLoaded()) return null; + if (Mods.Optifine.isModLoaded()) return null; BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker); SCHEDULED_BLOOM_RENDERS.add(ticket); return ticket; @@ -253,7 +253,7 @@ public boolean test(BloomRenderTicket bloomRenderTicket) { public static void init() { bloom = EnumHelper.addEnum(BlockRenderLayer.class, "BLOOM", new Class[] { String.class }, "Bloom"); BLOOM = bloom; - if (Loader.isModLoaded("nothirium")) { + if (Mods.Nothirium.isModLoaded()) { try { // Nothirium hard copies the BlockRenderLayer enum into a ChunkRenderPass enum. Add our BLOOM layer to // that too. @@ -285,7 +285,7 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, Minecraft mc = Minecraft.getMinecraft(); mc.profiler.endStartSection("BTLayer"); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } diff --git a/src/main/java/gregtech/client/utils/DepthTextureUtil.java b/src/main/java/gregtech/client/utils/DepthTextureUtil.java index 3aa59bf75b4..d3bd1c4f06d 100644 --- a/src/main/java/gregtech/client/utils/DepthTextureUtil.java +++ b/src/main/java/gregtech/client/utils/DepthTextureUtil.java @@ -1,6 +1,6 @@ package gregtech.client.utils; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -40,7 +40,7 @@ public class DepthTextureUtil { private static int lastWidth, lastHeight; private static boolean shouldRenderDepthTexture() { - return lastBind && !Shaders.isOptiFineShaderPackLoaded() && ConfigHolder.client.hookDepthTexture && + return lastBind && !Mods.Optifine.isModLoaded() && ConfigHolder.client.hookDepthTexture && OpenGlHelper.isFramebufferEnabled(); } diff --git a/src/main/java/gregtech/client/utils/ItemRenderCompat.java b/src/main/java/gregtech/client/utils/ItemRenderCompat.java index bff1b3e5cb9..4ea385c8910 100644 --- a/src/main/java/gregtech/client/utils/ItemRenderCompat.java +++ b/src/main/java/gregtech/client/utils/ItemRenderCompat.java @@ -1,12 +1,11 @@ package gregtech.client.utils; -import gregtech.api.GTValues; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.util.world.DummyWorld; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import appeng.items.misc.ItemEncodedPattern; import org.jetbrains.annotations.ApiStatus; @@ -74,7 +73,7 @@ public interface RepresentativeStackExtractor { private static final class AE2StackExtractor implements RepresentativeStackExtractor { public static @Nullable ItemRenderCompat.AE2StackExtractor create() { - if (!Loader.isModLoaded(GTValues.MODID_APPENG)) return null; + if (!Mods.AppliedEnergistics2.isModLoaded()) return null; GTLog.logger.info("AppliedEnergistics2 found; enabling render integration."); return new AE2StackExtractor(); } @@ -112,7 +111,7 @@ private RSStackExtractor(MethodHandle getPatternFromCacheHandle, MethodHandle ge } public static @Nullable ItemRenderCompat.RSStackExtractor create() { - if (!Loader.isModLoaded(GTValues.MODID_RS)) return null; + if (!Mods.RefinedStorage.isModLoaded()) return null; Class clazz; try { diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 6cda26f8ce5..69bf9e9640c 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -1,11 +1,11 @@ package gregtech.common.items.behaviors; -import gregtech.api.GTValues; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.GradientUtil; +import gregtech.api.util.Mods; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; @@ -23,7 +23,6 @@ import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; @@ -93,7 +92,7 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos world.setBlockState(pos, newBlockState); return true; } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { TileEntity te = world.getTileEntity(pos); if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; @@ -146,7 +145,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc } // AE2 cable special case - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; // do not try to strip color if it is already colorless diff --git a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java index 15a3ebc2599..f5ce22ba925 100644 --- a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java @@ -5,6 +5,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.util.Mods; import gregtech.integration.baubles.BaublesModule; import net.minecraft.client.resources.I18n; @@ -26,7 +27,6 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.jetbrains.annotations.NotNull; @@ -162,7 +162,7 @@ public void onItemToss(@NotNull ItemTossEvent event) { if (event.getPlayer() == null) return; IInventory inventory = event.getPlayer().inventory; - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventory = BaublesModule.getBaublesWrappedInventory(event.getPlayer()); } diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 2ab4fcce70c..0cbbb62b64e 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -13,6 +13,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -51,7 +52,6 @@ import gregtech.integration.jei.multiblock.MultiblockInfoCategory; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.Loader; import java.util.HashMap; import java.util.Map; @@ -1094,7 +1094,7 @@ public static void init() { // organization. // ME Hatches, IDs 1745-1748 - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { FLUID_EXPORT_HATCH_ME = registerMetaTileEntity(1745, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); ITEM_EXPORT_BUS_ME = registerMetaTileEntity(1746, @@ -1215,7 +1215,7 @@ public static T registerMetaTileEntity(int id, T samp if (sampleMetaTileEntity instanceof IMultiblockAbilityPart abilityPart) { MultiblockAbility.registerMultiblockAbility(abilityPart.getAbility(), sampleMetaTileEntity); } - if (sampleMetaTileEntity instanceof MultiblockControllerBase && Loader.isModLoaded(GTValues.MODID_JEI)) { + if (sampleMetaTileEntity instanceof MultiblockControllerBase && Mods.JustEnoughItems.isModLoaded()) { if (((MultiblockControllerBase) sampleMetaTileEntity).shouldShowInJei()) { MultiblockInfoCategory.registerMultiblock((MultiblockControllerBase) sampleMetaTileEntity); } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java index 926f7386174..f953dff1b4e 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.PipelineUtil; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; @@ -19,7 +20,6 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.api.util.AECableType; @@ -89,21 +89,21 @@ public void addInformation(ItemStack stack, @Nullable World player, List @Override public void update() { super.update(); - if (isFirstTick() && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (isFirstTick() && Mods.AppliedEnergistics2.isModLoaded()) { if (getProxy() != null) getProxy().onReady(); } } @NotNull @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.SMART; } @Nullable @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { if (gridProxy == null && getHolder() instanceof MetaTileEntityHolder) { gridProxy = new AENetworkProxy((MetaTileEntityHolder) getHolder(), "proxy", getStackForm(), true); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java index 0c34ab575ec..c09b9b91203 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java @@ -28,6 +28,7 @@ import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.util.BlockInfo; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -64,7 +65,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -543,7 +543,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.7")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.8")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.9")); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { tooltip.add(I18n.format(AEConfig.instance().isFeatureEnabled(AEFeature.CHANNELS) ? "gregtech.machine.cleanroom.tooltip.ae2.channels" : "gregtech.machine.cleanroom.tooltip.ae2.no_channels")); diff --git a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java index 56a96fb43ca..1439a5c5554 100644 --- a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java +++ b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java @@ -13,6 +13,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pattern.*; +import gregtech.api.util.Mods; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -449,7 +450,7 @@ public static void addWallBlock(@NotNull Block block) { } @ZenMethod("addWallBlock") - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @SuppressWarnings("unused") public static void addWallBlockCT(@NotNull IBlock block) { WALL_BLOCKS.add(CraftTweakerMC.getBlock(block)); diff --git a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java b/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java index 106b142c66f..ba42b1a29cc 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java +++ b/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java @@ -1,6 +1,5 @@ package gregtech.common.terminal.app.prospector.widget; -import gregtech.api.GTValues; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.Widget; import gregtech.api.unification.OreDictUnifier; @@ -33,7 +32,6 @@ import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -308,8 +306,7 @@ public void drawInForeground(int mouseX, int mouseY) { } } - if (Loader.isModLoaded(GTValues.MODID_JOURNEYMAP) || Loader.isModLoaded(GTValues.MODID_VOXELMAP) || - Loader.isModLoaded(GTValues.MODID_XAERO_MINIMAP)) { + if (Mods.JourneyMap.isModLoaded() || Mods.VoxelMap.isModLoaded() || Mods.XaerosMinimap.isModLoaded()) { tooltips.add(I18n.format("terminal.prospector.waypoint.add")); } this.drawHoveringText(ItemStack.EMPTY, tooltips, 300, mouseX, mouseY); @@ -336,11 +333,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { boolean added = false; trimHoveredNames(); - if (Loader.isModLoaded(GTValues.MODID_JOURNEYMAP)) { + if (Mods.JourneyMap.isModLoaded()) { added = addJourneymapWaypoint(b); - } else if (Loader.isModLoaded(GTValues.MODID_VOXELMAP)) { + } else if (Mods.VoxelMap.isModLoaded()) { added = addVoxelMapWaypoint(b); - } else if (Loader.isModLoaded(GTValues.MODID_XAERO_MINIMAP)) { + } else if (Mods.XaerosMinimap.isModLoaded()) { added = addXaeroMapWaypoint(b); } if (added) { @@ -382,7 +379,7 @@ private String createVeinName() { return s.substring(1, s.length() - 1); } - @Optional.Method(modid = GTValues.MODID_JOURNEYMAP) + @Optional.Method(modid = Mods.Names.JOURNEY_MAP) private boolean addJourneymapWaypoint(BlockPos b) { journeymap.client.model.Waypoint journeyMapWaypoint = new journeymap.client.model.Waypoint(createVeinName(), b, @@ -396,7 +393,7 @@ private boolean addJourneymapWaypoint(BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_VOXELMAP) + @Optional.Method(modid = Mods.Names.VOXEL_MAP) private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { Color c = new Color(color); TreeSet world = new TreeSet<>(); @@ -425,7 +422,7 @@ private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_XAERO_MINIMAP) + @Optional.Method(modid = Mods.Names.XAEROS_MINIMAP) private boolean addXaeroMapWaypoint(@NotNull BlockPos b) { int red = clampColor(color >> 16 & 0xFF); int green = clampColor(color >> 8 & 0xFF); diff --git a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java index f4b7fe6f2e1..8ead4466af8 100644 --- a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java +++ b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java @@ -17,6 +17,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.client.shader.Shaders; import gregtech.client.utils.DepthTextureUtil; import gregtech.client.utils.RenderBufferHelper; @@ -490,7 +491,7 @@ private static void renderScan(float getPartialTicks) { Minecraft mc = Minecraft.getMinecraft(); World world = mc.world; Entity viewer = mc.getRenderViewEntity(); - if (world != null && viewer != null && !Shaders.isOptiFineShaderPackLoaded()) { + if (world != null && viewer != null && !Mods.Optifine.isModLoaded()) { Framebuffer fbo = mc.getFramebuffer(); diff --git a/src/main/java/gregtech/integration/IntegrationModule.java b/src/main/java/gregtech/integration/IntegrationModule.java index 15d760b4a63..65f02e3c938 100644 --- a/src/main/java/gregtech/integration/IntegrationModule.java +++ b/src/main/java/gregtech/integration/IntegrationModule.java @@ -2,12 +2,12 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.modules.BaseGregTechModule; import gregtech.modules.GregTechModules; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -47,13 +47,13 @@ public List> getEventBusSubscribers() { public void init(FMLInitializationEvent event) { super.init(event); - if (Loader.isModLoaded(GTValues.MODID_IE)) { + if (Mods.ImmersiveEngineering.isModLoaded()) { BelljarHandler.registerBasicItemFertilizer(MetaItems.FERTILIZER.getStackForm(), 1.25f); logger.info("Registered Immersive Engineering Compat"); } } - @Optional.Method(modid = GTValues.MODID_EIO) + @Optional.Method(modid = Mods.Names.ENDER_IO) @SubscribeEvent public static void registerFertilizer(@NotNull RegistryEvent.Register event) { event.getRegistry().register(new Bonemeal(MetaItems.FERTILIZER.getStackForm())); diff --git a/src/main/java/gregtech/integration/IntegrationUtil.java b/src/main/java/gregtech/integration/IntegrationUtil.java index 88cfe6ec990..c25edab7be0 100644 --- a/src/main/java/gregtech/integration/IntegrationUtil.java +++ b/src/main/java/gregtech/integration/IntegrationUtil.java @@ -11,6 +11,7 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,9 +19,16 @@ import java.util.Arrays; import java.util.List; +@Deprecated public class IntegrationUtil { - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibilityIfLoaded(String modID, String... customMessages) { if (Loader.isModLoaded(modID)) { String modName = TextFormatting.BOLD + modID + TextFormatting.RESET; @@ -31,7 +39,13 @@ public static void throwIncompatibilityIfLoaded(String modID, String... customMe } } - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibility(List messages) { if (FMLLaunchHandler.side() == Side.SERVER) { throw new RuntimeException(String.join(",", messages)); @@ -40,16 +54,31 @@ public static void throwIncompatibility(List messages) { } } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta) { return getModItem(modid, name, meta, 1, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount) { return getModItem(modid, name, meta, amount, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount, @Nullable String nbt) { diff --git a/src/main/java/gregtech/integration/baubles/BaublesModule.java b/src/main/java/gregtech/integration/baubles/BaublesModule.java index 4371d5a032d..6f725211e8f 100644 --- a/src/main/java/gregtech/integration/baubles/BaublesModule.java +++ b/src/main/java/gregtech/integration/baubles/BaublesModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.integration.IntegrationSubmodule; import gregtech.modules.GregTechModules; @@ -24,7 +25,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_BAUBLES, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_BAUBLES, + modDependencies = Mods.Names.BAUBLES, name = "GregTech Baubles Integration", description = "Baubles Integration Module") public class BaublesModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/chisel/ChiselModule.java b/src/main/java/gregtech/integration/chisel/ChiselModule.java index c6dc3cafe05..c8a5f8d3416 100644 --- a/src/main/java/gregtech/integration/chisel/ChiselModule.java +++ b/src/main/java/gregtech/integration/chisel/ChiselModule.java @@ -5,6 +5,7 @@ import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockColored; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockWarningSign; @@ -31,7 +32,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CHISEL, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CHISEL, + modDependencies = Mods.Names.CHISEL, name = "GregTech Chisel Integration", description = "Chisel Integration Module") public class ChiselModule extends IntegrationSubmodule { @@ -110,7 +111,7 @@ private void addVariation(String group, Block block, int meta) { tag.setString("group", group); tag.setString("block", Objects.requireNonNull(block.getRegistryName()).toString()); tag.setInteger("meta", meta); - FMLInterModComms.sendMessage(GTValues.MODID_CHISEL, "add_variation", tag); + FMLInterModComms.sendMessage(Mods.Names.CHISEL, "add_variation", tag); } private boolean doesGroupExist(String group) { diff --git a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java index 400c41a1110..37fb6535fe5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java +++ b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java @@ -4,6 +4,7 @@ import gregtech.api.items.metaitem.MetaOreDictItem; import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.crafttweaker.recipe.MetaItemBracketHandler; @@ -27,7 +28,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CT, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CT, + modDependencies = Mods.Names.CRAFT_TWEAKER, name = "GregTech CraftTweaker Integration", description = "CraftTweaker Integration Module") public class CraftTweakerModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java index b8dc8e77a9b..d12a134adc5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java @@ -1,6 +1,5 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.FluidState; import gregtech.api.fluids.store.FluidStorageKey; @@ -14,6 +13,7 @@ import gregtech.api.unification.material.properties.ToolProperty; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -264,7 +264,7 @@ public CTMaterialBuilder itemPipeProperties(int priority, float stacksPerSec) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public CTMaterialBuilder addDefaultEnchant(IEnchantment enchantment) { Enchantment enchantmentType = (Enchantment) enchantment.getDefinition().getInternal(); backingBuilder.addDefaultEnchant(enchantmentType, enchantment.getLevel()); diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java index 3f8e854cb29..aeef7c2ac07 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java @@ -1,11 +1,11 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.store.FluidStorageKeys; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.*; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -65,7 +65,7 @@ public static boolean isGaseous(Material m) { // TODO May need to move this to Material @ZenGetter("fluid") - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static ILiquidDefinition getFluid(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); if (prop != null) { @@ -164,13 +164,13 @@ public static int toolEnchant(Material m) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addToolEnchantment(Material m, IEnchantment enchantment) { addScaledToolEnchantment(m, enchantment, 0); } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addScaledToolEnchantment(Material m, IEnchantment enchantment, double levelGrowth) { if (checkFrozen("add tool enchantment")) return; ToolProperty prop = m.getProperty(PropertyKey.TOOL); diff --git a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java index 76d76eb64c9..287b9a9e647 100644 --- a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java +++ b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java @@ -1,6 +1,6 @@ package gregtech.integration.ctm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.block.state.IBlockState; import net.minecraft.util.EnumFacing; @@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull; import team.chisel.ctm.api.IFacade; -@Optional.Interface(modid = GTValues.MODID_CTM, iface = "team.chisel.ctm.api.IFacade") +@Optional.Interface(modid = Mods.Names.CONNECTED_TEXTURES_MOD, iface = "team.chisel.ctm.api.IFacade") public interface IFacadeWrapper extends IFacade { @NotNull diff --git a/src/main/java/gregtech/integration/forestry/ForestryModule.java b/src/main/java/gregtech/integration/forestry/ForestryModule.java index de316640666..b938f4ab228 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryModule.java +++ b/src/main/java/gregtech/integration/forestry/ForestryModule.java @@ -15,6 +15,7 @@ import gregtech.api.unification.material.properties.OreProperty; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.items.ToolItems; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; @@ -31,7 +32,6 @@ import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -52,7 +52,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_FR, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_FR, + modDependencies = Mods.Names.FORESTRY, name = "GregTech Forestry Integration", description = "Forestry Integration Module") public class ForestryModule extends IntegrationSubmodule { @@ -100,7 +100,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Frames if (ForestryConfig.enableGTFrames) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { FRAME_ACCELERATED = new GTItemFrame(GTFrameType.ACCELERATED); FRAME_MUTAGENIC = new GTItemFrame(GTFrameType.MUTAGENIC); FRAME_WORKING = new GTItemFrame(GTFrameType.WORKING); @@ -126,7 +126,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Bees if (ForestryConfig.enableGTBees) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { DROPS = new GTDropItem(); COMBS = new GTCombItem(); } else { @@ -137,7 +137,7 @@ public void preInit(FMLPreInitializationEvent event) { // Remove duplicate/conflicting bees from other Forestry addons. // Done in init to have our changes applied before their registration, // since we load after other Forestry addons purposefully. - if (ForestryConfig.disableConflictingBees && ForestryUtil.apicultureEnabled()) { + if (ForestryConfig.disableConflictingBees && Mods.ForestryApiculture.isModLoaded()) { BeeRemovals.init(); } @@ -154,7 +154,7 @@ public void init(FMLInitializationEvent event) { ForestryElectrodeRecipes.onInit(); } - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.harderForestryRecipes) { ForestryMiscRecipes.initRemoval(); } @@ -165,12 +165,12 @@ public void init(FMLInitializationEvent event) { } } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { registerAlvearyMutators(); } if (event.getSide() == Side.CLIENT) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> { if (stack.getItem() instanceof IColoredItem coloredItem) { @@ -185,7 +185,7 @@ public void init(FMLInitializationEvent event) { @Override public void postInit(FMLPostInitializationEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { getLogger().info("Copying Forestry Centrifuge recipes to GT Centrifuge"); CombRecipes.initForestryCombs(); } @@ -196,7 +196,7 @@ public static void registerItems(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); // GT Frames - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { registry.register(FRAME_ACCELERATED); registry.register(FRAME_MUTAGENIC); @@ -222,20 +222,19 @@ public static void registerItems(RegistryEvent.Register event) { ELECTRODE_OBSIDIAN = forestryMetaItem.addItem(10, "electrode.obsidian"); ELECTRODE_TIN = forestryMetaItem.addItem(11, "electrode.tin"); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_IRON = forestryMetaItem.addItem(12, "electrode.iron"); } - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { ELECTRODE_ORCHID = forestryMetaItem.addItem(13, "electrode.orchid"); } - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_RUBBER = forestryMetaItem.addItem(14, "electrode.rubber"); } } // GT Drops - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { registry.register(DROPS); registry.register(COMBS); @@ -246,7 +245,7 @@ public static void registerItems(RegistryEvent.Register event) { @SideOnly(Side.CLIENT) @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { FRAME_ACCELERATED.registerModel(FRAME_ACCELERATED, ForestryAPI.modelManager); FRAME_MUTAGENIC.registerModel(FRAME_MUTAGENIC, ForestryAPI.modelManager); @@ -265,7 +264,7 @@ public static void registerModels(ModelRegistryEvent event) { @SubscribeEvent public static void registerRecipes(RegistryEvent.Register event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { // GT Frames if (ForestryConfig.enableGTFrames) { ForestryFrameRecipes.init(); @@ -294,7 +293,7 @@ public static void registerRecipes(RegistryEvent.Register event) { @SubscribeEvent public static void registerMaterials(MaterialEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { Materials.TreatedWood.addFlags(MaterialFlags.GENERATE_LONG_ROD); Materials.Uranium235.addFlags(MaterialFlags.GENERATE_LONG_ROD); diff --git a/src/main/java/gregtech/integration/forestry/ForestryUtil.java b/src/main/java/gregtech/integration/forestry/ForestryUtil.java index 32fff8e1e19..1bc2a8df6c0 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryUtil.java +++ b/src/main/java/gregtech/integration/forestry/ForestryUtil.java @@ -1,6 +1,6 @@ package gregtech.integration.forestry; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.forestry.bees.GTCombType; import gregtech.integration.forestry.bees.GTDropType; @@ -11,52 +11,39 @@ import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAlleleFlowers; -import forestry.modules.ModuleHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ForestryUtil { - public static boolean apicultureEnabled() { - return ModuleHelper.isEnabled("apiculture"); - } - - public static boolean arboricultureEnabled() { - return ModuleHelper.isEnabled("arboriculture"); - } - - public static boolean lepidopterologyEnabled() { - return ModuleHelper.isEnabled("lepidopterology"); - } - @Nullable - public static IAlleleBeeEffect getEffect(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.effect." + name; - case GTValues.MODID_MB -> "magicbees.effect" + name; - case GTValues.MODID -> "gregtech.effect." + name; + public static IAlleleBeeEffect getEffect(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.effect." + name; + case MagicBees -> "magicbees.effect" + name; + case GregTech -> "gregtech.effect." + name; default -> "forestry.effect" + name; }; return (IAlleleBeeEffect) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleFlowers getFlowers(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.flower." + name; - case GTValues.MODID_MB -> "magicbees.flower" + name; - case GTValues.MODID -> "gregtech.flower." + name; + public static IAlleleFlowers getFlowers(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.flower." + name; + case MagicBees -> "magicbees.flower" + name; + case GregTech -> "gregtech.flower." + name; default -> "forestry.flowers" + name; }; return (IAlleleFlowers) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleBeeSpecies getSpecies(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.species." + name; - case GTValues.MODID_MB -> "magicbees.species" + name; - case GTValues.MODID -> "gregtech.species." + name; + public static IAlleleBeeSpecies getSpecies(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.species." + name; + case MagicBees -> "magicbees.species" + name; + case GregTech -> "gregtech.species." + name; default -> "forestry.species" + name; }; return (IAlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele(s); @@ -74,7 +61,7 @@ public static ItemStack getCombStack(@NotNull GTCombType type, int amount) { .error("Tried to get GregTech Comb stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Comb stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } @@ -93,7 +80,7 @@ public static ItemStack getDropStack(@NotNull GTDropType type, int amount) { .error("Tried to get GregTech Drop stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Drop stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } diff --git a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java index 65546dfe020..39dcb08e103 100644 --- a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java +++ b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java @@ -1,10 +1,8 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; -import net.minecraftforge.fml.common.Loader; - import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -16,10 +14,10 @@ public class BeeRemovals { private static final List EB_REMOVALS = new ArrayList<>(); public static void init() { - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { removeMagicBees(); } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { removeExtraBees(); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java index 891a8277bc9..0bd8d25bf53 100644 --- a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java +++ b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.machines.IScannerRecipeMap; -import gregtech.integration.forestry.ForestryUtil; +import gregtech.api.util.Mods; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -60,7 +60,7 @@ public List getRepresentativeRecipes() { List recipes = new ArrayList<>(); ItemStack outputStack; - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { outputStack = ModuleApiculture.getItems().beeDroneGE.getItemStack(); outputStack.setTagCompound(BeeDefinition.COMMON.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.drone"); @@ -98,7 +98,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.arboricultureEnabled()) { + if (Mods.ForestryArboriculture.isModLoaded()) { outputStack = ModuleArboriculture.getItems().sapling.getItemStack(); outputStack.setTagCompound(TreeDefinition.Oak.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.sapling"); @@ -118,7 +118,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.lepidopterologyEnabled()) { + if (Mods.ForestryLepidopterology.isModLoaded()) { outputStack = ModuleLepidopterology.getItems().butterflyGE.getItemStack(); outputStack .setTagCompound(ButterflyDefinition.CabbageWhite.getIndividual().writeToNBT(new NBTTagCompound())); diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 269e992be1b..d4a967e4bfe 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -5,9 +5,9 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryModule; import gregtech.integration.forestry.ForestryUtil; @@ -15,7 +15,6 @@ import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.common.BiomeDictionary; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.core.Api; @@ -48,7 +47,7 @@ public enum GTBeeDefinition implements IBeeDefinition { // Organic CLAY(GTBranchDefinition.GT_ORGANIC, "Lutum", true, 0xC8C8DA, 0x0000FF, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(22), 0.30f); // CLAY } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -56,8 +55,8 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addProduct(new ItemStack(Items.CLAY_BALL), 0.15f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_BOP)) { - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_BOP, "mudball", 0), 0.05f); + if (Mods.BiomesOPlenty.isModLoaded()) { + beeSpecies.addSpecialty(Mods.BiomesOPlenty.getItem("mudball", 0), 0.05f); } }, template -> { @@ -77,10 +76,9 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(getGTComb(GTCombType.STICKY), 0.05f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_TCON)) { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_TCON, "edible", 1), 0.10f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_TCON, "slime_congealed", 2), - 0.01f); + if (Mods.TinkersConstruct.isModLoaded()) { + beeSpecies.addProduct(Mods.TinkersConstruct.getItem("edible", 1), 0.10f); + beeSpecies.addSpecialty(Mods.TinkersConstruct.getItem("slime_congealed", 2), 0.01f); } else { beeSpecies.addSpecialty(new ItemStack(Blocks.SLIME_BLOCK), 0.01f); } @@ -90,9 +88,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.BOTH_1); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.BOTH_1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> { @@ -167,15 +165,15 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.NONE); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.NONE); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> dis.registerMutation(COAL, STICKYRESIN, 4)), ASH(GTBranchDefinition.GT_ORGANIC, "Cinis", true, 0x1E1A18, 0xC6C6C6, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.30f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -197,7 +195,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), APATITE(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.15f); @@ -211,9 +209,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.LONGER); AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, EnumAllele.Flowers.WHEAT); AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "rock")); + ForestryUtil.getFlowers(Mods.ExtraBees, "rock")); } }, dis -> { @@ -239,7 +237,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), FERTILIZER(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.MOSSY), 0.15f); @@ -247,7 +245,7 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.Ash), 0.2f); beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.DarkAsh), 0.2f); beeSpecies.addSpecialty(MetaItems.FERTILIZER.getStackForm(), 0.3f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0), 0.3f); + beeSpecies.addSpecialty(Mods.Forestry.getItem("fertilizer_compound", 0), 0.3f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.WARM); }, @@ -273,16 +271,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }), SANDWICH(GTBranchDefinition.GT_ORGANIC, "Sandwico", true, 0x32CD32, 0xDAA520, beeSpecies -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 81), 0.05f); // Cucumber - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 80), 0.05f); // Onion - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 79), 0.05f); // Tomato - // Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 81), 0.05f); // Cucumber Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 80), 0.05f); // Onion Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 79), 0.05f); // Tomato Slice beeSpecies.addSpecialty(new ItemStack(Items.COOKED_PORKCHOP), 0.05f); beeSpecies.addSpecialty(new ItemStack(Items.COOKED_BEEF), 0.15f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 97), 0.05f); // Cheddar - // Slice + beeSpecies.addSpecialty(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 97), 0.05f); // Cheddar Slice beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); }, @@ -296,14 +290,13 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB)) { - dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Batty"), - 10); + if (Mods.MagicBees.isModLoaded()) { + dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(Mods.MagicBees, "Batty"), 10); } else { dis.registerMutation(BeeDefinition.AGRARIAN, BeeDefinition.IMPERIAL, 10); } }, - () -> Loader.isModLoaded(GTValues.MODID_GTFO)), + Mods.GregTechFoodOption::isModLoaded), // Gems REDSTONE(GTBranchDefinition.GT_GEM, "Rubrumlapis", true, 0x7D0F0F, 0xD11919, @@ -357,7 +350,7 @@ public enum GTBeeDefinition implements IBeeDefinition { Api.INSTANCE.definitions().blocks().fluixBlock().maybeBlock() .ifPresent(block -> mutation.requireResource(block.getDefaultState())); }, - () -> Loader.isModLoaded(GTValues.MODID_APPENG)), + Mods.AppliedEnergistics2::isModLoaded), DIAMOND(GTBranchDefinition.GT_GEM, "Adamas", false, 0xCCFFFF, 0xA3CCCC, beeSpecies -> { beeSpecies.addProduct(getGTComb(GTCombType.STONE), 0.30f); @@ -422,7 +415,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), SPARKLING(GTBranchDefinition.GT_GEM, "Vesperstella", true, 0x7A007A, 0xFFFFFF, beeSpecies -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 3), 0.20f); + beeSpecies.addProduct(Mods.MagicBees.getItem("resource", 3), 0.20f); beeSpecies.addSpecialty(getGTComb(GTCombType.SPARKLING), 0.125f); beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); @@ -438,12 +431,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation( - ForestryUtil.getSpecies(GTValues.MODID_MB, "Withering"), - ForestryUtil.getSpecies(GTValues.MODID_MB, "Draconic"), 1); + ForestryUtil.getSpecies(Mods.MagicBees, "Withering"), + ForestryUtil.getSpecies(Mods.MagicBees, "Draconic"), 1); mutation.requireResource("blockNetherStar"); mutation.restrictBiomeType(BiomeDictionary.Type.END); }, - () -> Loader.isModLoaded(GTValues.MODID_MB)), + Mods.MagicBees::isModLoaded), // Metals COPPER(GTBranchDefinition.GT_METAL, "Cuprum", true, 0xFF6600, 0xE65C00, @@ -588,9 +581,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, TOLERATES_RAIN, true); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB) && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.MagicBees.isModLoaded() && Mods.AppliedEnergistics2.isModLoaded()) { // MB Skystone bee is only registered if AE2 is also active - dis.registerMutation(IRON, ForestryUtil.getSpecies(GTValues.MODID_MB, "AESkystone"), 17); + dis.registerMutation(IRON, ForestryUtil.getSpecies(Mods.MagicBees, "AESkystone"), 17); } else { dis.registerMutation(IRON, BeeDefinition.IMPERIAL, 17); } @@ -768,7 +761,7 @@ public enum GTBeeDefinition implements IBeeDefinition { // Industrial ENERGY(GTBranchDefinition.GT_INDUSTRIAL, "Industria", false, 0xC11F1F, 0xEBB9B9, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(14), 0.30f); // STATIC } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.SIMMERING), 0.30f); @@ -789,9 +782,9 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { mutation = dis.registerMutation(BeeDefinition.DEMONIC, - ForestryUtil.getSpecies(GTValues.MODID_EB, "volcanic"), 10); + ForestryUtil.getSpecies(Mods.ExtraBees, "volcanic"), 10); } else { mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.FIENDISH, 10); } @@ -988,8 +981,8 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { - mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(GTValues.MODID_EB, "rotten"), 1); + if (Mods.ExtraBees.isModLoaded()) { + mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(Mods.ExtraBees, "rotten"), 1); } else { mutation = dis.registerMutation(THORIUM, BeeDefinition.IMPERIAL, 1); } @@ -1041,9 +1034,9 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { mutation = dis.registerMutation(STAINLESSSTEEL, - ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 10); + ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 10); } else { mutation = dis.registerMutation(STAINLESSSTEEL, BeeDefinition.INDUSTRIOUS, 10); } @@ -1060,9 +1053,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 8); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 8); } else { mutation = dis.registerMutation(HELIUM, BeeDefinition.IMPERIAL, 8); } @@ -1092,9 +1084,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 4); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 4); } else { mutation = dis.registerMutation(NEON, BeeDefinition.AVENGING, 4); } @@ -1139,8 +1130,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 15); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 15); } else { mutation = dis.registerMutation(OXYGEN, BeeDefinition.INDUSTRIOUS, 15); } @@ -1233,14 +1224,14 @@ private static ItemStack getForestryComb(EnumHoneyComb type) { return ModuleApiculture.getItems().beeComb.get(type, 1); } - @Optional.Method(modid = GTValues.MODID_EB) + @Optional.Method(modid = Mods.Names.EXTRA_BEES) private static ItemStack getExtraBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_comb", meta); + return Mods.ExtraBees.getItem("honey_comb", meta); } - @Optional.Method(modid = GTValues.MODID_MB) + @Optional.Method(modid = Mods.Names.MAGIC_BEES) private static ItemStack getMagicBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_MB, "beecomb", meta); + return Mods.MagicBees.getItem("beecomb", meta); } private static ItemStack getGTComb(GTCombType type) { diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java index 0769ad034bf..e037872f2cf 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; @@ -37,7 +38,7 @@ public GTCombItem() { public void registerModel(@NotNull Item item, IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTCombType.values().length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.comb"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.comb"); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java index f774e6f68d0..e17fc00a429 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java @@ -1,8 +1,6 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; - -import net.minecraftforge.fml.common.Loader; +import gregtech.api.util.Mods; public enum GTCombType { @@ -27,7 +25,7 @@ public enum GTCombType { // Gem STONE("stone", 0x808080, 0x999999), CERTUS("certus", 0x57CFFB, 0xBBEEFF), - FLUIX("fluix", 0xA375FF, 0xB591FF, Loader.isModLoaded(GTValues.MODID_APPENG)), + FLUIX("fluix", 0xA375FF, 0xB591FF, Mods.AppliedEnergistics2.isModLoaded()), REDSTONE("redstone", 0x7D0F0F, 0xD11919), RAREEARTH("rareearth", 0x555643, 0x343428), LAPIS("lapis", 0x1947D1, 0x476CDA), @@ -38,7 +36,7 @@ public enum GTCombType { EMERALD("emerald", 0x248F24, 0x2EB82E), PYROPE("pyrope", 0x763162, 0x8B8B8B), GROSSULAR("grossular", 0x9B4E00, 0x8B8B8B), - SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Loader.isModLoaded(GTValues.MODID_MB)), + SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Mods.MagicBees.isModLoaded()), // Metal SLAG("slag", 0xD4D4D4, 0x58300B), diff --git a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java index 45a67068b2a..a8453a6a151 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; @@ -44,7 +45,7 @@ private void setResearchSuitability(@Nullable ISpeciesRoot speciesRoot) { public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTDropType.VALUES.length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.honey_drop"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.honey_drop"); } } diff --git a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java index 088c5ed7e73..e8f9a46d45e 100644 --- a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java +++ b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.frames; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.Item; @@ -62,7 +63,7 @@ public IBeeModifier getBeeModifier() { @SuppressWarnings("deprecation") @Override public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { - manager.registerItemModel(item, 0, GTValues.MODID_FR, "gt.frame_" + type.getName().toLowerCase()); + manager.registerItemModel(item, 0, Mods.Names.FORESTRY, "gt.frame_" + type.getName().toLowerCase()); } public ItemStack getItemStack() { diff --git a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java index 66df87dc408..a7661982176 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java @@ -12,8 +12,8 @@ import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTCombItem; import gregtech.integration.forestry.bees.GTCombType; @@ -21,7 +21,6 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import appeng.core.Api; import com.google.common.collect.ImmutableMap; @@ -98,8 +97,8 @@ public static void initGTCombs() { ModuleCore.getItems().refractoryWax.getItemStack() }, new int[] { 20 * 100, 50 * 100 }, Voltage.HV, 196); ItemStack wax = ModuleCore.getItems().beeswax.getItemStack(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - wax = IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 2); + if (Mods.MagicBees.isModLoaded()) { + wax = Mods.MagicBees.getItem("wax", 2); } addCentrifugeToItemStack(GTCombType.LAPOTRON, new ItemStack[] { OreDictUnifier.get(OrePrefix.dust, Materials.Lapotron), wax }, @@ -271,11 +270,10 @@ public static void initGTCombs() { .cleanroom(CleanroomType.CLEANROOM) .duration(3000).EUt(Voltage.UV.getChemicalEnergy()).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { addProcessGT(GTCombType.SPARKLING, new Material[] { Materials.NetherStar }, Voltage.EV); addCentrifugeToItemStack(GTCombType.SPARKLING, - new ItemStack[] { IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 0), - IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 5), + new ItemStack[] { Mods.MagicBees.getItem("wax", 0), Mods.MagicBees.getItem("resource", 5), OreDictUnifier.get(OrePrefix.dustTiny, Materials.NetherStar) }, new int[] { 50 * 100, 10 * 100, 10 * 100 }, Voltage.EV); } @@ -290,7 +288,7 @@ public static void initGTCombs() { addExtractorProcess(GTCombType.HYDROGEN, Materials.Hydrogen.getFluid(500), Voltage.MV, 100); addExtractorProcess(GTCombType.FLUORINE, Materials.Fluorine.getFluid(250), Voltage.MV, 128); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { ItemStack fluixDust = OreDictUnifier.get("dustFluix"); if (fluixDust == ItemStack.EMPTY) { fluixDust = Api.INSTANCE.definitions().materials().fluixDust().maybeStack(1).orElse(ItemStack.EMPTY); diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java index 171f575bc32..72014ca62c6 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java @@ -1,14 +1,13 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.integration.forestry.ForestryModule; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.core.ModuleCore; @@ -137,7 +136,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_GOLD, 2) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_IRON) .fluidInputs(Glass.getFluid(100)) @@ -176,7 +175,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_OBSIDIAN, 4) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_ORCHID) .fluidInputs(Glass.getFluid(100)) @@ -191,8 +190,7 @@ public static void addGregTechMachineRecipes() { } // todo mixin forestry to allow this tube always, since we have rubber (once mixin port is done) - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_RUBBER) .fluidInputs(Glass.getFluid(100)) @@ -248,7 +246,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(wireGtSingle, RedAlloy).toString(), 'X', new UnificationEntry(plate, Bronze).toString()); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.IRON, "SXS", "#X#", "XXX", 'S', new UnificationEntry(screw, Iron).toString(), @@ -301,7 +299,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(plate, EnderEye).toString(), 'X', new ItemStack(Blocks.END_STONE)); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.ORCHID, " X ", "#X#", "XXX", '#', new ItemStack(Items.REPEATER), diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java index 5a57da584cc..e1face8fe9e 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java @@ -1,16 +1,14 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; -import gregtech.integration.IntegrationUtil; +import gregtech.api.util.Mods; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.core.fluids.Fluids; @@ -18,171 +16,107 @@ public class ForestryExtractorRecipes { public static void init() { // Commonly used items - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); - ItemStack propolis = IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); + ItemStack propolis = Mods.Forestry.getItem("propolis"); // Vanilla Fruit Juice items addFruitJuiceRecipe(new ItemStack(Items.CARROT), 200, GTUtility.copy(mulch), 2000); addFruitJuiceRecipe(new ItemStack(Items.APPLE), 200, GTUtility.copy(mulch), 2000); // Forestry fruits - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 0), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 1), 180, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 2), 220, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 3), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 4), 100, GTUtility.copy(mulch), - 6000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 5), 50, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 6), 600, GTUtility.copy(mulch), - 1000); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 0), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 1), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 2), 220, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 3), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 4), 100, GTUtility.copy(mulch), 6000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 5), 50, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 6), 600, GTUtility.copy(mulch), 1000); // Honey, Honeydew - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0), 100, GTUtility.copy(propolis), - 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honeydew", 0), 100); + addHoneyRecipe(Mods.Forestry.getItem("honey_drop"), 100, GTUtility.copy(propolis), 0); + addHoneyRecipe(Mods.Forestry.getItem("honeydew"), 100); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { // Propolis - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 0), - Materials.Water.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 1), - Materials.Oil.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 2), - Materials.Creosote.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 0), Materials.Water.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 1), Materials.Oil.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 2), Materials.Creosote.getFluid(500)); // Drops - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 3), 200); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 6), - Fluids.MILK.getFluid(200)); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 13), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 19), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 14), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 20), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 15), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 21), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 16), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 22), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 17), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 24), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 18), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 23), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 19), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 25), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 20), 200, - new ItemStack(Items.DYE, 1, 14), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 21), 200, - new ItemStack(Items.DYE, 1, 6), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 22), 200, - new ItemStack(Items.DYE, 1, 5), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 23), 200, - new ItemStack(Items.DYE, 1, 8), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 24), 200, - new ItemStack(Items.DYE, 1, 12), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 25), 200, - new ItemStack(Items.DYE, 1, 9), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 26), 200, - new ItemStack(Items.DYE, 1, 10), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 27), 200, - new ItemStack(Items.DYE, 1, 13), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 28), 200, - new ItemStack(Items.DYE, 1, 7), 0); + addFruitJuiceRecipe(Mods.ExtraBees.getItem("honey_drop", 3), 200); + addExtractorRecipe(Mods.ExtraBees.getItem("honey_drop", 6), Fluids.MILK.getFluid(200)); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 13), 200, Mods.ExtraBees.getItem("misc", 19), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 14), 200, Mods.ExtraBees.getItem("misc", 20), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 15), 200, Mods.ExtraBees.getItem("misc", 21), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 16), 200, Mods.ExtraBees.getItem("misc", 22), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 17), 200, Mods.ExtraBees.getItem("misc", 24), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 18), 200, Mods.ExtraBees.getItem("misc", 23), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 19), 200, Mods.ExtraBees.getItem("misc", 25), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 20), 200, new ItemStack(Items.DYE, 1, 14), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 21), 200, new ItemStack(Items.DYE, 1, 6), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 22), 200, new ItemStack(Items.DYE, 1, 5), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 23), 200, new ItemStack(Items.DYE, 1, 8), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 24), 200, new ItemStack(Items.DYE, 1, 12), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 25), 200, new ItemStack(Items.DYE, 1, 9), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 26), 200, new ItemStack(Items.DYE, 1, 10), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 27), 200, new ItemStack(Items.DYE, 1, 13), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 28), 200, new ItemStack(Items.DYE, 1, 7), 0); } - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { // Fruits - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 0), 150, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 1), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 2), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 3), 300, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 4), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 5), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 6), 50, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 7), 50, GTUtility.copy(mulch), - 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 8), 100, GTUtility.copy(mulch), - 6000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 9), 80, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 10), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 11), 500, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 12), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 13), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 14), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 15), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 16), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 17), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 18), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 19), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 20), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 21), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 22), 300, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 23), 200, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 24), 150, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 25), 180, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 26), 100, GTUtility.copy(mulch), - 400); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 27), 50, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 28), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 29), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 30), 100, GTUtility.copy(mulch), - 4000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 31), 20, GTUtility.copy(mulch), 200); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 32), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 33), 50, GTUtility.copy(mulch), 300); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 34), 100, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 35), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 36), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 37), 20, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 38), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 39), 25, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 46), 50, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 50), 300, GTUtility.copy(mulch), - 2500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 51), 150, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 52), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 53), 50, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 54), 50, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 55), 100, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 56), 100, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 57), 400, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 58), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 59), 50, GTUtility.copy(mulch), - 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 0), 150, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 1), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 2), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 3), 300, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 4), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 5), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 6), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 7), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 8), 100, GTUtility.copy(mulch), 6000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 9), 80, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 10), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 11), 500, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 12), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 13), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 14), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 15), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 16), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 17), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 18), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 19), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 20), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 21), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 22), 300, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 23), 200, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 24), 150, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 25), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 26), 100, GTUtility.copy(mulch), 400); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 27), 50, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 28), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 29), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 30), 100, GTUtility.copy(mulch), 4000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 31), 20, GTUtility.copy(mulch), 200); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 32), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 33), 50, GTUtility.copy(mulch), 300); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 34), 100, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 35), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 36), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 37), 20, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 38), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 39), 25, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 46), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 50), 300, GTUtility.copy(mulch), 2500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 51), 150, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 52), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 53), 50, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 54), 50, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 55), 100, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 56), 100, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 57), 400, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 58), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 59), 50, GTUtility.copy(mulch), 1000); } } diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java index 5f4f214c294..85239b0a1a5 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java @@ -6,8 +6,8 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryConfig; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTDropType; @@ -15,7 +15,6 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.apiculture.ModuleApiculture; @@ -28,7 +27,7 @@ public class ForestryMiscRecipes { public static void init() { - if (ForestryConfig.enableGTBees) { + if (ForestryConfig.enableGTBees && Mods.ForestryApiculture.isModLoaded()) { // Oil Drop ItemStack dropStack = ForestryUtil.getDropStack(GTDropType.OIL); RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() @@ -45,8 +44,8 @@ public static void init() { // Biomass Drop dropStack = ForestryUtil.getDropStack(GTDropType.BIOMASS); ItemStack propolisStack = ModuleApiculture.getItems().propolis.get(EnumPropolis.NORMAL, 1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { - propolisStack = IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 7); + if (Mods.ExtraBees.isModLoaded()) { + propolisStack = Mods.ExtraBees.getItem("propolis", 7); } RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() .inputs(dropStack) @@ -202,7 +201,7 @@ public static void init() { } // Fertilizer - ItemStack fertilizer = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0); + ItemStack fertilizer = Mods.Forestry.getItem("fertilizer_compound"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .input(OrePrefix.dust, Materials.Apatite) @@ -224,8 +223,8 @@ public static void init() { .outputs(GTUtility.copy(30, fertilizer)) .duration(100).EUt(16).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - ItemStack concentratedCompound = IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 2); + if (Mods.MagicBees.isModLoaded()) { + ItemStack concentratedCompound = Mods.MagicBees.getItem("resource", 2); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .inputs(GTUtility.copy(concentratedCompound)) @@ -249,7 +248,7 @@ public static void init() { } // Compost - ItemStack compost = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_bio", 0); + ItemStack compost = Mods.Forestry.getItem("fertilizer_bio"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(Blocks.DIRT, 1, true) .input(Items.WHEAT, 4) @@ -279,19 +278,19 @@ public static void init() { // Phosphor RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "phosphor", 0)) + .inputs(Mods.Forestry.getItem("phosphor")) .chancedOutput(OrePrefix.dust, Materials.Phosphorus, 1000, 0) .fluidOutputs(Materials.Lava.getFluid(800)) .duration(256).EUt(GTValues.VA[GTValues.MV]).buildAndRegister(); // Ice Shard RecipeMaps.MACERATOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "crafting_material", 5)) + .inputs(Mods.Forestry.getItem("crafting_material", 5)) .output(OrePrefix.dust, Materials.Ice) .duration(16).EUt(4).buildAndRegister(); // Mulch - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); RecipeMaps.CHEMICAL_BATH_RECIPES.recipeBuilder() .input(MetaItems.BIO_CHAFF) .fluidInputs(Materials.Water.getFluid(750)) @@ -300,9 +299,9 @@ public static void init() { .chancedOutput(GTUtility.copy(4, mulch), 2000, 0) .duration(500).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { RecipeMaps.MIXER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_ET, "misc", 1)) + .inputs(Mods.ExtraTrees.getItem("misc", 1)) .fluidInputs(Materials.Water.getFluid(500)) .outputs(GTUtility.copy(mulch)) .duration(600).EUt(2).buildAndRegister(); @@ -328,7 +327,7 @@ public static void init() { .duration(900).EUt(10).buildAndRegister(); // Humus - ItemStack humus = IntegrationUtil.getModItem(GTValues.MODID_FR, "humus", 0); + ItemStack humus = Mods.Forestry.getItem("humus"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .inputs(GTUtility.copy(2, mulch)) .input(Blocks.DIRT, 2, true) @@ -362,35 +361,35 @@ public static void init() { .input(OrePrefix.plate, Materials.Tin, 2) .input(Blocks.GLASS_PANE) .circuitMeta(1) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "can", 0)) + .outputs(Mods.Forestry.getItem("can")) .duration(120).EUt(7).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "beeswax", 0)) + .inputs(Mods.Forestry.getItem("beeswax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "capsule", 0)) + .outputs(Mods.Forestry.getItem("capsule")) .duration(64).EUt(16).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory_wax", 0)) + .inputs(Mods.Forestry.getItem("refractory_wax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory", 0)) + .outputs(Mods.Forestry.getItem("refractory")) .duration(128).EUt(16).buildAndRegister(); // Propolis RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0)) + .inputs(Mods.Forestry.getItem("propolis")) .output(MetaItems.STICKY_RESIN) .duration(128).EUt(5).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { // DNA Dye RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Glowstone) .input("dyePurple") .input("dyeBlue") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 1, 8)) + .outputs(Mods.Genetics.getItem("misc", 1, 8)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Fluorescent Dye @@ -398,14 +397,14 @@ public static void init() { .input(OrePrefix.dust, Materials.Glowstone) .input("dyeOrange") .input("dyeYellow") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 2, 2)) + .outputs(Mods.Genetics.getItem("misc", 2, 2)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Growth Medium RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Sugar) .input(OrePrefix.dust, Materials.Bone) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 4, 2)) + .outputs(Mods.Genetics.getItem("misc", 4, 2)) .duration(400).EUt(16).buildAndRegister(); } @@ -413,7 +412,7 @@ public static void init() { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) .fluidInputs(Fluids.FOR_HONEY.getFluid(200)) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0)) + .outputs(Mods.Forestry.getItem("honey_drop")) .duration(400).EUt(7).buildAndRegister(); RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() @@ -425,7 +424,7 @@ public static void init() { public static void initRemoval() { ModHandler.removeRecipeByName("forestry:sand_to_fertilizer"); ModHandler.removeRecipeByName("forestry:ash_to_fertilizer"); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { ModHandler.removeRecipeByName("magicbees:fertilizer1"); ModHandler.removeRecipeByName("magicbees:fertilizer2"); ModHandler.removeRecipeByName("magicbees:fertilizer3"); @@ -437,7 +436,7 @@ public static void initRemoval() { ModHandler.removeRecipeByName("forestry:tin_can"); ModHandler.removeRecipeByName("forestry:wax_capsule"); ModHandler.removeRecipeByName("forestry:refractory_capsule"); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { ModHandler.removeRecipeByName("genetics:dna_dye_from_glowstone"); ModHandler.removeRecipeByName("genetics:dna_dye"); ModHandler.removeRecipeByName("genetics:fluorescent_dye"); diff --git a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java index 221fadaa6f6..6eed93239d8 100644 --- a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java +++ b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java @@ -1,8 +1,8 @@ package gregtech.integration.forestry.tools; -import gregtech.api.GTValues; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.items.toolitem.behavior.IToolBehavior; +import gregtech.api.util.Mods; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; @@ -13,7 +13,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.fml.common.Loader; import forestry.api.lepidopterology.EnumFlutterType; import forestry.api.lepidopterology.IAlleleButterflySpecies; @@ -32,7 +31,7 @@ private ScoopBehavior() {/**/} @Override public void hitEntity(@NotNull ItemStack stack, @NotNull EntityLivingBase target, @NotNull EntityLivingBase attacker) { - if (!Loader.isModLoaded(GTValues.MODID_FR)) return; + if (!Mods.Forestry.isModLoaded()) return; if (!(target instanceof IEntityButterfly butterfly)) return; if (!(attacker instanceof EntityPlayer player)) return; if (attacker.world == null || attacker.world.isRemote) return; diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index adb308fe4e6..b6b603bb07e 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -10,6 +10,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; @@ -46,13 +47,13 @@ import java.util.Objects; import java.util.function.Supplier; -@Optional.Interface(modid = GTValues.MODID_GROOVYSCRIPT, +@Optional.Interface(modid = Mods.Names.GROOVY_SCRIPT, iface = "com.cleanroommc.groovyscript.api.GroovyPlugin", striprefs = true) @GregTechModule( moduleID = GregTechModules.MODULE_GRS, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_GROOVYSCRIPT, + modDependencies = Mods.Names.GROOVY_SCRIPT, name = "GregTech GroovyScript Integration", description = "GroovyScript Integration Module") public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPlugin { diff --git a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java index bce36365fc0..d26defcbde3 100644 --- a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java +++ b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.hwyla.provider.*; import gregtech.modules.GregTechModules; @@ -17,7 +18,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_HWYLA, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_HWYLA, + modDependencies = Mods.Names.HWYLA, name = "GregTech HWYLA Integration", description = "HWYLA (WAILA) Integration Module") public class HWYLAModule extends IntegrationSubmodule implements IWailaPlugin { diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 5c89ad0bb61..35e3f525ec3 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -20,6 +20,7 @@ import gregtech.api.recipes.machines.RecipeMapFurnace; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.BedrockFluidDepositDefinition; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.config.WorldGenRegistry; @@ -68,7 +69,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_JEI, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_JEI, + modDependencies = Mods.Names.JUST_ENOUGH_ITEMS, name = "GregTech JEI Integration", description = "JustEnoughItems Integration Module") public class JustEnoughItemsModule extends IntegrationSubmodule implements IModPlugin { diff --git a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java index 0f5bd90bf9f..75d8c11f81a 100644 --- a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java +++ b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java @@ -4,6 +4,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.util.FileUtility; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.FillerConfigUtils; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.filler.BlockFiller; @@ -26,7 +27,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidBlock; -import net.minecraftforge.fml.common.Loader; import com.google.common.collect.ImmutableList; import mezz.jei.api.ingredients.IIngredients; @@ -41,7 +41,6 @@ import java.util.function.Function; import static gregtech.api.GTValues.M; -import static gregtech.api.GTValues.MODID_CC; public class GTOreInfo implements IRecipeWrapper { @@ -64,7 +63,7 @@ public GTOreInfo(OreDepositDefinition definition) { // Don't default to vanilla Maximums and minimums if the values are not defined and Cubic Chunks is loaded // This could be improved to use the actual minimum and maximum heights, at the cost of including the CC Api - if (Loader.isModLoaded(MODID_CC)) { + if (Mods.CubicChunks.isModLoaded()) { this.maxHeight = definition.getMaximumHeight() == Integer.MAX_VALUE ? Integer.MAX_VALUE : definition.getMaximumHeight(); this.minHeight = definition.getMinimumHeight() == Integer.MIN_VALUE ? Integer.MIN_VALUE : diff --git a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java index 77ee3c8bcb7..bc5042b0d64 100644 --- a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java +++ b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java @@ -1,6 +1,7 @@ package gregtech.integration.jei.utils; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.OreDepositDefinition; import net.minecraft.client.Minecraft; @@ -10,7 +11,6 @@ import net.minecraft.world.WorldProvider; import net.minecraft.world.biome.Biome; import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.fml.common.Loader; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntArrayList; @@ -27,8 +27,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import static gregtech.api.GTValues.MODID_AR; - /** * Common util methods shared between {@link gregtech.integration.jei.basic.GTOreCategory} * and {@link gregtech.integration.jei.basic.GTFluidVeinCategory} @@ -139,7 +137,7 @@ public static int[] getAllRegisteredDimensions(@Nullable Predicate Date: Wed, 31 Jan 2024 11:30:42 +0800 Subject: [PATCH 069/168] Update zh_cn.lang (#2362) --- .../resources/assets/gregtech/lang/zh_cn.lang | 226 +++++++++--------- 1 file changed, 114 insertions(+), 112 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index adbc85e0853..afd9ee25e54 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -924,7 +924,7 @@ metaitem.wooden_form.brick.name=木制砖模具 item.gt.tool.replace_tool_head=在合成栏用新的工具头替换 item.gt.tool.usable_as=可用作:§f%s -item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰 +item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰块 item.gt.tool.behavior.torch_place=§e洞窟探客:§f右击可放置火把 item.gt.tool.behavior.tree_felling=§4伐木好手:§f一次性砍下整棵树木 item.gt.tool.behavior.shield_disable=§c野兽蛮攻:§f破除盾牌 @@ -1650,7 +1650,7 @@ gregtech.material.rose_gold=玫瑰金 gregtech.material.black_bronze=黑青铜 gregtech.material.bismuth_bronze=铋青铜 gregtech.material.biotite=黑云母 -gregtech.material.powellite=钼钨钙矿 +gregtech.material.powellite=钼钙矿 gregtech.material.pyrite=黄铁矿 gregtech.material.pyrolusite=软锰矿 gregtech.material.pyrope=镁铝榴石 @@ -2918,9 +2918,9 @@ gregtech.machine.steam_hammer_bronze.tooltip=锤锻机器 gregtech.machine.steam_hammer_steel.name=高压蒸汽锻造锤 gregtech.machine.steam_hammer_steel.tooltip=锤锻机器 gregtech.machine.steam_furnace_bronze.name=蒸汽熔炉 -gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_furnace_steel.name=高压蒸汽熔炉 -gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_alloy_smelter_bronze.name=蒸汽合金炉 gregtech.machine.steam_alloy_smelter_bronze.tooltip=熔合冶炼炉 gregtech.machine.steam_alloy_smelter_steel.name=高压合金炉 @@ -2999,9 +2999,9 @@ gregtech.machine.macerator.lv.tooltip=粉碎矿石 gregtech.machine.macerator.mv.name=进阶研磨机 gregtech.machine.macerator.mv.tooltip=粉碎矿石 gregtech.machine.macerator.hv.name=进阶研磨机 II -gregtech.machine.macerator.hv.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.hv.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.ev.name=进阶研磨机 III -gregtech.machine.macerator.ev.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.ev.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.iv.name=精英研磨机 gregtech.machine.macerator.iv.tooltip=全自动破壁机 9001 gregtech.machine.macerator.luv.name=精英研磨机 II @@ -3059,11 +3059,11 @@ gregtech.machine.arc_furnace.hv.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.ev.name=进阶电弧炉 III gregtech.machine.arc_furnace.ev.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.iv.name=精英电弧炉 -gregtech.machine.arc_furnace.iv.tooltip=解体加热器 +gregtech.machine.arc_furnace.iv.tooltip=放电加热器 gregtech.machine.arc_furnace.luv.name=精英电弧炉 II -gregtech.machine.arc_furnace.luv.tooltip=解体加热器 +gregtech.machine.arc_furnace.luv.tooltip=放电加热器 gregtech.machine.arc_furnace.zpm.name=精英电弧炉 III -gregtech.machine.arc_furnace.zpm.tooltip=解体加热器 +gregtech.machine.arc_furnace.zpm.tooltip=放电加热器 gregtech.machine.arc_furnace.uv.name=终极电弧炉 gregtech.machine.arc_furnace.uv.tooltip=短路加热器 gregtech.machine.arc_furnace.uhv.name=史诗电弧炉 @@ -3285,23 +3285,23 @@ gregtech.machine.chemical_reactor.hv.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.ev.name=进阶化学反应釜 III gregtech.machine.chemical_reactor.ev.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.iv.name=精英化学反应釜 -gregtech.machine.chemical_reactor.iv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.iv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.luv.name=精英化学反应釜 II -gregtech.machine.chemical_reactor.luv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.luv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.zpm.name=精英化学反应釜 III -gregtech.machine.chemical_reactor.zpm.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.zpm.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.uv.name=终极化学反应釜 -gregtech.machine.chemical_reactor.uv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uhv.name=史诗化学反应釜 -gregtech.machine.chemical_reactor.uhv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uhv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uev.name=史诗化学反应釜 II -gregtech.machine.chemical_reactor.uev.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uev.tooltip=反应催化器 gregtech.machine.chemical_reactor.uiv.name=史诗化学反应釜 III -gregtech.machine.chemical_reactor.uiv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uiv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uxv.name=史诗化学反应釜 IV -gregtech.machine.chemical_reactor.uxv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uxv.tooltip=反应催化器 gregtech.machine.chemical_reactor.opv.name=传奇化学反应釜 -gregtech.machine.chemical_reactor.opv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.opv.tooltip=反应催化器 # Compressor gregtech.machine.compressor.lv.name=基础压缩机 @@ -3347,17 +3347,17 @@ gregtech.machine.cutter.luv.tooltip=物质切削器 gregtech.machine.cutter.zpm.name=精英切割机 III gregtech.machine.cutter.zpm.tooltip=物质切削器 gregtech.machine.cutter.uv.name=终极切割机 -gregtech.machine.cutter.uv.tooltip=物品对象分割者 +gregtech.machine.cutter.uv.tooltip=对象分割者 gregtech.machine.cutter.uhv.name=史诗切割机 -gregtech.machine.cutter.uhv.tooltip=物品对象分割者 +gregtech.machine.cutter.uhv.tooltip=对象分割者 gregtech.machine.cutter.uev.name=史诗切割机 II -gregtech.machine.cutter.uev.tooltip=物品对象分割者 +gregtech.machine.cutter.uev.tooltip=对象分割者 gregtech.machine.cutter.uiv.name=史诗切割机 III -gregtech.machine.cutter.uiv.tooltip=物品对象分割者 +gregtech.machine.cutter.uiv.tooltip=对象分割者 gregtech.machine.cutter.uxv.name=史诗切割机 IV -gregtech.machine.cutter.uxv.tooltip=物品对象分割者 +gregtech.machine.cutter.uxv.tooltip=对象分割者 gregtech.machine.cutter.opv.name=传奇切割机 -gregtech.machine.cutter.opv.tooltip=物品对象分割者 +gregtech.machine.cutter.opv.tooltip=对象分割者 # Distillery gregtech.machine.distillery.lv.name=基础蒸馏室 @@ -3375,17 +3375,17 @@ gregtech.machine.distillery.luv.tooltip=凝结物质分离器 gregtech.machine.distillery.zpm.name=精英蒸馏室 III gregtech.machine.distillery.zpm.tooltip=凝结物质分离器 gregtech.machine.distillery.uv.name=终极蒸馏室 -gregtech.machine.distillery.uv.tooltip=少数分流者 +gregtech.machine.distillery.uv.tooltip=馏分分离器 gregtech.machine.distillery.uhv.name=史诗蒸馏室 -gregtech.machine.distillery.uhv.tooltip=少数分流者 +gregtech.machine.distillery.uhv.tooltip=馏分分离器 gregtech.machine.distillery.uev.name=史诗蒸馏室 II -gregtech.machine.distillery.uev.tooltip=少数分流者 +gregtech.machine.distillery.uev.tooltip=馏分分离器 gregtech.machine.distillery.uiv.name=史诗蒸馏室 III -gregtech.machine.distillery.uiv.tooltip=少数分流者 +gregtech.machine.distillery.uiv.tooltip=馏分分离器 gregtech.machine.distillery.uxv.name=史诗蒸馏室 IV -gregtech.machine.distillery.uxv.tooltip=少数分流者 +gregtech.machine.distillery.uxv.tooltip=馏分分离器 gregtech.machine.distillery.opv.name=传奇蒸馏室 -gregtech.machine.distillery.opv.tooltip=少数分流者 +gregtech.machine.distillery.opv.tooltip=馏分分离器 # Electrolyzer gregtech.machine.electrolyzer.lv.name=基础电解机 @@ -3445,13 +3445,13 @@ gregtech.machine.electromagnetic_separator.opv.tooltip=电磁场驱离装置 # Extractor gregtech.machine.extractor.lv.name=基础提取机 -gregtech.machine.extractor.lv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.lv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.mv.name=进阶提取机 -gregtech.machine.extractor.mv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.mv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.hv.name=进阶提取机 II -gregtech.machine.extractor.hv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.hv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.ev.name=进阶提取机 III -gregtech.machine.extractor.ev.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.ev.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.iv.name=精英提取机 gregtech.machine.extractor.iv.tooltip=真空提炼机 gregtech.machine.extractor.luv.name=精英提取机 II @@ -3473,13 +3473,13 @@ gregtech.machine.extractor.opv.tooltip=液化吸取者 # Extruder gregtech.machine.extruder.lv.name=基础压模器 -gregtech.machine.extruder.lv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.lv.tooltip=通用型金属加工器 gregtech.machine.extruder.mv.name=进阶压模器 -gregtech.machine.extruder.mv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.mv.tooltip=通用型金属加工器 gregtech.machine.extruder.hv.name=进阶压模器 II -gregtech.machine.extruder.hv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.hv.tooltip=通用型金属加工器 gregtech.machine.extruder.ev.name=进阶压模器 III -gregtech.machine.extruder.ev.tooltip=通用的金属处理机器 +gregtech.machine.extruder.ev.tooltip=通用型金属加工器 gregtech.machine.extruder.iv.name=精英压模器 gregtech.machine.extruder.iv.tooltip=材料压出器 gregtech.machine.extruder.luv.name=精英压模器 II @@ -3508,11 +3508,11 @@ gregtech.machine.fermenter.hv.tooltip=发酵流体 gregtech.machine.fermenter.ev.name=进阶发酵槽 III gregtech.machine.fermenter.ev.tooltip=发酵流体 gregtech.machine.fermenter.iv.name=精英发酵槽 -gregtech.machine.fermenter.iv.tooltip=发酵催促器 +gregtech.machine.fermenter.iv.tooltip=发酵加速器 gregtech.machine.fermenter.luv.name=精英发酵槽 II -gregtech.machine.fermenter.luv.tooltip=发酵催促器 +gregtech.machine.fermenter.luv.tooltip=发酵加速器 gregtech.machine.fermenter.zpm.name=精英发酵槽 III -gregtech.machine.fermenter.zpm.tooltip=发酵催促器 +gregtech.machine.fermenter.zpm.tooltip=发酵加速器 gregtech.machine.fermenter.uv.name=终极发酵槽 gregtech.machine.fermenter.uv.tooltip=呼吸控制器 gregtech.machine.fermenter.uhv.name=史诗发酵槽 @@ -3528,41 +3528,41 @@ gregtech.machine.fermenter.opv.tooltip=呼吸控制器 # Fluid Heater gregtech.machine.fluid_heater.lv.name=基础流体加热器 -gregtech.machine.fluid_heater.lv.tooltip=加热流体 +gregtech.machine.fluid_heater.lv.tooltip=加热你的流体 gregtech.machine.fluid_heater.mv.name=进阶流体加热器 -gregtech.machine.fluid_heater.mv.tooltip=加热流体 +gregtech.machine.fluid_heater.mv.tooltip=加热你的流体 gregtech.machine.fluid_heater.hv.name=进阶流体加热器 II -gregtech.machine.fluid_heater.hv.tooltip=加热流体 +gregtech.machine.fluid_heater.hv.tooltip=加热你的流体 gregtech.machine.fluid_heater.ev.name=进阶流体加热器 III -gregtech.machine.fluid_heater.ev.tooltip=加热流体 +gregtech.machine.fluid_heater.ev.tooltip=加热你的流体 gregtech.machine.fluid_heater.iv.name=精英流体加热器 -gregtech.machine.fluid_heater.iv.tooltip=热量注入器 +gregtech.machine.fluid_heater.iv.tooltip=热量灌注器 gregtech.machine.fluid_heater.luv.name=精英流体加热器 II -gregtech.machine.fluid_heater.luv.tooltip=热量注入器 +gregtech.machine.fluid_heater.luv.tooltip=热量灌注器 gregtech.machine.fluid_heater.zpm.name=精英流体加热器 III -gregtech.machine.fluid_heater.zpm.tooltip=热量注入器 +gregtech.machine.fluid_heater.zpm.tooltip=热量灌注器 gregtech.machine.fluid_heater.uv.name=终极流体加热器 -gregtech.machine.fluid_heater.uv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uhv.name=史诗流体加热器 -gregtech.machine.fluid_heater.uhv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uhv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uev.name=史诗流体加热器 II -gregtech.machine.fluid_heater.uev.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uev.tooltip=热量灌输器 gregtech.machine.fluid_heater.uiv.name=史诗流体加热器 III -gregtech.machine.fluid_heater.uiv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uiv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uxv.name=史诗流体加热器 IV -gregtech.machine.fluid_heater.uxv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uxv.tooltip=热量灌输器 gregtech.machine.fluid_heater.opv.name=传奇流体加热器 -gregtech.machine.fluid_heater.opv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.opv.tooltip=热量灌输器 # Fluid Solidifier gregtech.machine.fluid_solidifier.lv.name=基础流体固化器 -gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.mv.name=进阶流体固化器 -gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.hv.name=进阶流体固化器 II -gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.ev.name=进阶流体固化器 III -gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.iv.name=精英流体固化器 gregtech.machine.fluid_solidifier.iv.tooltip=并不是制冰机 gregtech.machine.fluid_solidifier.luv.name=精英流体固化器 II @@ -3592,11 +3592,11 @@ gregtech.machine.forge_hammer.hv.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.ev.name=进阶锻造锤 III gregtech.machine.forge_hammer.ev.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.iv.name=精英锻造锤 -gregtech.machine.forge_hammer.iv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.iv.tooltip=锻板机 gregtech.machine.forge_hammer.luv.name=精英锻造锤 II -gregtech.machine.forge_hammer.luv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.luv.tooltip=锻板机 gregtech.machine.forge_hammer.zpm.name=精英锻造锤 III -gregtech.machine.forge_hammer.zpm.tooltip=板材锻造机 +gregtech.machine.forge_hammer.zpm.tooltip=锻板机 gregtech.machine.forge_hammer.uv.name=终极锻造锤 gregtech.machine.forge_hammer.uv.tooltip=冲击调制器 gregtech.machine.forge_hammer.uhv.name=史诗锻造锤 @@ -3612,13 +3612,13 @@ gregtech.machine.forge_hammer.opv.tooltip=冲击调制器 # Forming Press gregtech.machine.forming_press.lv.name=基础冲压机床 -gregtech.machine.forming_press.lv.tooltip=将印象压印为实际的存在 +gregtech.machine.forming_press.lv.tooltip=图像拓印者 gregtech.machine.forming_press.mv.name=进阶冲压机床 -gregtech.machine.forming_press.mv.tooltip=印象具现者 +gregtech.machine.forming_press.mv.tooltip=图像拓印者 gregtech.machine.forming_press.hv.name=进阶冲压机床 II -gregtech.machine.forming_press.hv.tooltip=印象具现者 +gregtech.machine.forming_press.hv.tooltip=图像拓印者 gregtech.machine.forming_press.ev.name=进阶冲压机床 III -gregtech.machine.forming_press.ev.tooltip=印象具现者 +gregtech.machine.forming_press.ev.tooltip=图像拓印者 gregtech.machine.forming_press.iv.name=精英冲压机床 gregtech.machine.forming_press.iv.tooltip=对象层化机 gregtech.machine.forming_press.luv.name=精英冲压机床 II @@ -3752,13 +3752,13 @@ gregtech.machine.packer.opv.tooltip=亚马逊仓库 # Polarizer gregtech.machine.polarizer.lv.name=基础两极磁化机 -gregtech.machine.polarizer.lv.tooltip=使磁体两极化 +gregtech.machine.polarizer.lv.tooltip=将你的磁体极化 gregtech.machine.polarizer.mv.name=进阶两极磁化机 -gregtech.machine.polarizer.mv.tooltip=使磁体两极化 +gregtech.machine.polarizer.mv.tooltip=将你的磁体极化 gregtech.machine.polarizer.hv.name=进阶两极磁化机 II -gregtech.machine.polarizer.hv.tooltip=使磁体两极化 +gregtech.machine.polarizer.hv.tooltip=将你的磁体极化 gregtech.machine.polarizer.ev.name=进阶两极磁化机 III -gregtech.machine.polarizer.ev.tooltip=使磁体两极化 +gregtech.machine.polarizer.ev.tooltip=将你的磁体极化 gregtech.machine.polarizer.iv.name=精英两极磁化机 gregtech.machine.polarizer.iv.tooltip=磁性引入机 gregtech.machine.polarizer.luv.name=精英两极磁化机 II @@ -3788,11 +3788,11 @@ gregtech.machine.laser_engraver.hv.tooltip=请勿直视激光 gregtech.machine.laser_engraver.ev.name=进阶精密激光蚀刻机 III gregtech.machine.laser_engraver.ev.tooltip=请勿直视激光 gregtech.machine.laser_engraver.iv.name=精英精密激光蚀刻机 -gregtech.machine.laser_engraver.iv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.iv.tooltip=功率高达两百零四万瓦 gregtech.machine.laser_engraver.luv.name=精英精密激光蚀刻机 II -gregtech.machine.laser_engraver.luv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.luv.tooltip=功率高达八百一十六万瓦 gregtech.machine.laser_engraver.zpm.name=精英精密激光蚀刻机 III -gregtech.machine.laser_engraver.zpm.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.zpm.tooltip=功率高达三千两百六十四万瓦 gregtech.machine.laser_engraver.uv.name=终极精密激光蚀刻机 gregtech.machine.laser_engraver.uv.tooltip=高精度光子加农炮 gregtech.machine.laser_engraver.uhv.name=史诗激光蚀刻机 @@ -3892,13 +3892,13 @@ gregtech.machine.wiremill.opv.tooltip=导线易形者 # Circuit Assembler gregtech.machine.circuit_assembler.lv.name=基础电路组装机 -gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.mv.name=进阶电路组装机 -gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.hv.name=进阶电路组装机 II -gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.ev.name=进阶电路组装机 III -gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.iv.name=精英电路组装机 gregtech.machine.circuit_assembler.iv.tooltip=电子厂 gregtech.machine.circuit_assembler.luv.name=精英电路组装机 II @@ -3906,17 +3906,17 @@ gregtech.machine.circuit_assembler.luv.tooltip=电子厂 gregtech.machine.circuit_assembler.zpm.name=精英电路组装机 III gregtech.machine.circuit_assembler.zpm.tooltip=电子厂 gregtech.machine.circuit_assembler.uv.name=终极电路组装机 -gregtech.machine.circuit_assembler.uv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uhv.name=史诗电路组装机 -gregtech.machine.circuit_assembler.uhv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uhv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uev.name=史诗电路组装机 II -gregtech.machine.circuit_assembler.uev.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uev.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uiv.name=史诗电路组装机 III -gregtech.machine.circuit_assembler.uiv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uiv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uxv.name=史诗电路组装机 IV -gregtech.machine.circuit_assembler.uxv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uxv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.opv.name=传奇电路组装机 -gregtech.machine.circuit_assembler.opv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.opv.tooltip=计算机工厂 # Mass Fabricator gregtech.machine.mass_fabricator.lv.name=基础质量发生器 @@ -3928,11 +3928,11 @@ gregtech.machine.mass_fabricator.hv.tooltip=UU物质 = “质量” * “发生 gregtech.machine.mass_fabricator.ev.name=进阶质量发生器 III gregtech.machine.mass_fabricator.ev.tooltip=UU物质 = “质量” * “发生”的平方 gregtech.machine.mass_fabricator.iv.name=精英质量发生器 -gregtech.machine.mass_fabricator.iv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.iv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.luv.name=精英质量发生器 II -gregtech.machine.mass_fabricator.luv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.luv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.zpm.name=精英质量发生器 III -gregtech.machine.mass_fabricator.zpm.tooltip=创世工坊 +gregtech.machine.mass_fabricator.zpm.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.uv.name=终极质量发生器 gregtech.machine.mass_fabricator.uv.tooltip=存在之源 gregtech.machine.mass_fabricator.uhv.name=史诗质量发生器 @@ -3948,13 +3948,13 @@ gregtech.machine.mass_fabricator.opv.tooltip=存在之源 # Replicator gregtech.machine.replicator.lv.name=基础复制机 -gregtech.machine.replicator.lv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.lv.tooltip=生产最纯净的元素 gregtech.machine.replicator.mv.name=进阶复制机 -gregtech.machine.replicator.mv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.mv.tooltip=生产最纯净的元素 gregtech.machine.replicator.hv.name=进阶复制机 II -gregtech.machine.replicator.hv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.hv.tooltip=生产最纯净的元素 gregtech.machine.replicator.ev.name=进阶复制机 III -gregtech.machine.replicator.ev.tooltip=生产出至纯的元素 +gregtech.machine.replicator.ev.tooltip=生产最纯净的元素 gregtech.machine.replicator.iv.name=精英复制机 gregtech.machine.replicator.iv.tooltip=物质粘贴机 gregtech.machine.replicator.luv.name=精英复制机 II @@ -4312,7 +4312,7 @@ gregtech.machine.quantum_tank.uv.name=量子缸 IV gregtech.machine.quantum_tank.uhv.name=量子缸 V #Buffers -gregtech.machine.buffer.tooltip=能够存储物品与流体的小型缓存器 +gregtech.machine.buffer.tooltip=用于存储物品和流体的小小缓冲器 gregtech.machine.buffer.lv.name=基础缓存器 gregtech.machine.buffer.mv.name=进阶缓存器 gregtech.machine.buffer.hv.name=进阶缓存器 II @@ -4330,31 +4330,31 @@ tile.hermetic_casing.hermetic_casing_uhv.name=密封机械方块 IX #Gas Collectors gregtech.machine.gas_collector.lv.name=基础集气室 -gregtech.machine.gas_collector.lv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.lv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.mv.name=进阶集气室 -gregtech.machine.gas_collector.mv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.mv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.hv.name=进阶集气室 II -gregtech.machine.gas_collector.hv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.hv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.ev.name=进阶集气室 III -gregtech.machine.gas_collector.ev.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.ev.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.iv.name=精英集气室 -gregtech.machine.gas_collector.iv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.iv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.luv.name=精英集气室 II -gregtech.machine.gas_collector.luv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.luv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.zpm.name=精英集气室 III -gregtech.machine.gas_collector.zpm.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.zpm.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.uv.name=终极集气室 -gregtech.machine.gas_collector.uv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uhv.name=史诗集气室 -gregtech.machine.gas_collector.uhv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uhv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uev.name=史诗集气室 II -gregtech.machine.gas_collector.uev.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uev.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uiv.name=史诗集气室 III -gregtech.machine.gas_collector.uiv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uiv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uxv.name=史诗集气室 IV -gregtech.machine.gas_collector.uxv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uxv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.opv.name=传说集气室 -gregtech.machine.gas_collector.opv.tooltip=从宇宙中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.opv.tooltip=依照维度从宇宙中收集种类各异的气体 #Rock Breakers gregtech.machine.rock_breaker.lv.name=基础碎岩机 @@ -4372,17 +4372,17 @@ gregtech.machine.rock_breaker.luv.tooltip=岩浆冷却固化器 R-9200 gregtech.machine.rock_breaker.zpm.name=精英碎岩机 III gregtech.machine.rock_breaker.zpm.tooltip=岩浆冷却固化器 R-10200 gregtech.machine.rock_breaker.uv.name=终极碎岩机 -gregtech.machine.rock_breaker.uv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uv.tooltip=火山成型室 gregtech.machine.rock_breaker.uhv.name=史诗碎岩机 -gregtech.machine.rock_breaker.uhv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uhv.tooltip=火山成型室 gregtech.machine.rock_breaker.uev.name=史诗碎岩机 II -gregtech.machine.rock_breaker.uev.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uev.tooltip=火山成型室 gregtech.machine.rock_breaker.uiv.name=史诗碎岩机 III -gregtech.machine.rock_breaker.uiv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uiv.tooltip=火山成型室 gregtech.machine.rock_breaker.uxv.name=史诗碎岩机 IV -gregtech.machine.rock_breaker.uxv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uxv.tooltip=火山成型室 gregtech.machine.rock_breaker.opv.name=传奇碎岩机 -gregtech.machine.rock_breaker.opv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.opv.tooltip=火山成型室 #Fisher gregtech.machine.fisher.lv.name=基础捕鱼机 @@ -4814,7 +4814,7 @@ gregtech.machine.power_substation.tooltip3=最多容许§f%d层电容§7。 gregtech.machine.power_substation.tooltip4=每§f24小时§7损失相当于总容量的§f1%%§7的能量。 gregtech.machine.power_substation.tooltip5=每个电容的损失上限为§f%,d EU/t§7。 gregtech.machine.power_substation.tooltip6=可以使用 -gregtech.machine.power_substation.tooltip6.5= 激光仓§7。 +gregtech.machine.power_substation.tooltip6.5=激光仓§7。 gregtech.multiblock.power_substation.description=蓄能变电站是一个用于储存大量能量的多方块结构,它最多可以容纳18层电容,每层都必须填充完整,这意味着你可以用空电容来填充空间。 gregtech.machine.active_transformer.name=有源变压器 @@ -5652,8 +5652,10 @@ gregtech.multiblock.computation.not_enough_computation=机器需要更多算力 gregtech.multiblock.power_substation.stored=存储:%s gregtech.multiblock.power_substation.capacity=容量:%s gregtech.multiblock.power_substation.passive_drain=被动损失:%s -gregtech.multiblock.power_substation.average_io=平均输入/输出:%s -gregtech.multiblock.power_substation.average_io_hover=蓄能变电站内部的平均能量变化 +gregtech.multiblock.power_substation.average_in=平均EU输入:%s +gregtech.multiblock.power_substation.average_out=平均EU输出:%s +gregtech.multiblock.power_substation.average_in_hover=蓄能变电站内部的平均功率输入 +gregtech.multiblock.power_substation.average_out_hover=蓄能变电站内部的平均功率输出 gregtech.multiblock.power_substation.time_to_fill=预计充满时间:%s gregtech.multiblock.power_substation.time_to_drain=预计耗空时间:%s gregtech.multiblock.power_substation.time_seconds=%s秒 From 15043f9c94688adc68983bb6fa9f7c4f1afc38bd Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:05:45 -0600 Subject: [PATCH 070/168] Clean up MetaTileEntities class formatting (#2371) --- .../metatileentities/MetaTileEntities.java | 140 ++++++------------ 1 file changed, 47 insertions(+), 93 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 0cbbb62b64e..156c0a63f81 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -62,91 +62,65 @@ public class MetaTileEntities { + // spotless:off + // HULLS public static final MetaTileEntityHull[] HULL = new MetaTileEntityHull[GTValues.V.length]; - public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no - // MAX - public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; /// no MAX - public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; // no MAX + public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX + public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; /// no MAX + public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX public static final MetaTileEntityDiode[] DIODES = new MetaTileEntityDiode[GTValues.V.length]; public static final MetaTileEntityBatteryBuffer[][] BATTERY_BUFFER = new MetaTileEntityBatteryBuffer[3][GTValues.V.length]; public static final MetaTileEntityCharger[] CHARGER = new MetaTileEntityCharger[GTValues.V.length]; + // SIMPLE MACHINES SECTION - public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BENDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BREWERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CUTTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] EXTRUDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] LATHE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] MIXER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] PACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] UNPACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] SIFTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] WIREMILL = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - // TODO Replication system - // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new - // SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - // - 1]; + public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication + // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication public static final SimpleMachineMetaTileEntity[] SCANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - 1]; public static final MetaTileEntityRockBreaker[] ROCK_BREAKER = new MetaTileEntityRockBreaker[GTValues.V.length - 1]; public static final MetaTileEntityMiner[] MINER = new MetaTileEntityMiner[GTValues.V.length - 1]; + // GENERATORS SECTION public static final SimpleGeneratorMetaTileEntity[] COMBUSTION_GENERATOR = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] STEAM_TURBINE = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] GAS_TURBINE = new SimpleGeneratorMetaTileEntity[4]; + // MULTIBLOCK PARTS SECTION public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; // ULV-UHV public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; @@ -157,39 +131,14 @@ public class MetaTileEntities { public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityMultiFluidHatch[] NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, - // LuV, - // ZPM, - // UV, UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, - // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, - // ZPM, UV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, ZPM, UV public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; @@ -228,6 +177,7 @@ public class MetaTileEntities { // Used for addons if they wish to disable certain tiers of machines private static final Map MID_TIER = new HashMap<>(); private static final Map HIGH_TIER = new HashMap<>(); + // STEAM AGE SECTION public static SteamCoalBoiler STEAM_BOILER_COAL_BRONZE; public static SteamCoalBoiler STEAM_BOILER_COAL_STEEL; @@ -261,6 +211,7 @@ public class MetaTileEntities { public static MetaTileEntityMaintenanceHatch CONFIGURABLE_MAINTENANCE_HATCH; public static MetaTileEntityAutoMaintenanceHatch AUTO_MAINTENANCE_HATCH; public static MetaTileEntityCleaningMaintenanceHatch CLEANING_MAINTENANCE_HATCH; + // MULTIBLOCKS SECTION public static MetaTileEntityPrimitiveBlastFurnace PRIMITIVE_BLAST_FURNACE; public static MetaTileEntityCokeOven COKE_OVEN; @@ -322,6 +273,7 @@ public class MetaTileEntities { public static MetaTileEntityCrate STAINLESS_STEEL_CRATE; public static MetaTileEntityCrate TITANIUM_CRATE; public static MetaTileEntityCrate TUNGSTENSTEEL_CRATE; + // MISC MACHINES SECTION public static MetaTileEntityWorkbench WORKBENCH; public static MetaTileEntityCreativeEnergy CREATIVE_ENERGY; @@ -340,6 +292,8 @@ public class MetaTileEntities { public static MetaTileEntityConverter[][] ENERGY_CONVERTER = new MetaTileEntityConverter[4][GTValues.V.length]; + //spotless:on + public static void init() { GTLog.logger.info("Registering MetaTileEntities"); From 3865f221ffcb3a6a971e796ba7c27033638e870f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 4 Feb 2024 13:25:18 -0700 Subject: [PATCH 071/168] Set Hardness and Resistance to LDP Blocks (#2370) --- .../gregtech/api/pipenet/longdist/BlockLongDistancePipe.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java index cb3a9a5abbb..d848f2ed5a1 100644 --- a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java +++ b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java @@ -35,6 +35,8 @@ public BlockLongDistancePipe(LongDistancePipeType pipeType) { setTranslationKey("long_distance_" + pipeType.getName() + "_pipeline"); setCreativeTab(GregTechAPI.TAB_GREGTECH); setHarvestLevel(ToolClasses.WRENCH, 1); + setHardness(2f); + setResistance(10f); } @Override From e5f0194a5d69f377d528d47df503d53b2116a774 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:27:09 -0600 Subject: [PATCH 072/168] Fix hasEnoughPower() check in ARL (#2365) --- .../capability/impl/AbstractRecipeLogic.java | 25 +++++-------------- .../capability/impl/PrimitiveRecipeLogic.java | 10 +++++--- .../api/capability/impl/RecipeLogicSteam.java | 17 +++++++++++++ .../impl/SteamMultiblockRecipeLogic.java | 17 +++++++++++++ 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index e00cdc21235..ce4eab33ac9 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -636,33 +636,20 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, * @param resultOverclock the overclock data to use. Format: {@code [EUt, duration]}. * @return true if there is enough energy to continue recipe progress */ - protected boolean hasEnoughPower(@NotNull int[] resultOverclock) { + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { // Format of resultOverclock: EU/t, duration - int totalEUt = resultOverclock[0] * resultOverclock[1]; + int recipeEUt = resultOverclock[0]; // RIP Ternary // Power Consumption case - if (totalEUt >= 0) { - int capacity; - // If the total consumed power is greater than half the internal capacity - if (totalEUt > getEnergyCapacity() / 2) { - // Only draw 1A of power from the internal buffer to allow for recharging of the internal buffer from - // external sources - capacity = resultOverclock[0]; - } else { - // If the total consumed power is less than half the capacity, just drain the whole thing - capacity = totalEUt; - } - - // Return true if we have enough energy stored to progress the recipe, either 1A or the whole amount - return getEnergyStored() >= capacity; + if (recipeEUt >= 0) { + // ensure it can run for at least 8 ticks. Arbitrary value, but should prevent instant failures + return getEnergyStored() >= ((long) recipeEUt << 3); } // Power Generation case else { - // This is the EU/t generated by the generator - int power = resultOverclock[0]; // Return true if we can fit at least 1A of energy into the energy output - return getEnergyStored() - (long) power <= getEnergyCapacity(); + return getEnergyStored() - (long) recipeEUt <= getEnergyCapacity(); } } diff --git a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java index 182b900ae3b..e3367929b06 100644 --- a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java @@ -38,15 +38,19 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) { return true; // spoof energy being drawn } + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + return true; + } + @Override public long getMaxVoltage() { return GTValues.LV; } - @NotNull @Override - protected int[] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, - long maxVoltage, int recipeDuration, int amountOC) { + protected int @NotNull [] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, + long maxVoltage, int recipeDuration, int amountOC) { return standardOverclockingLogic( 1, getMaxVoltage(), diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java index c5d7dcbb960..c1e4fc665a9 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java @@ -227,6 +227,23 @@ public long getMaxVoltage() { return GTValues.V[GTValues.LV]; } + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + int totalSteam = (int) (resultOverclock[0] * resultOverclock[1] / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(resultOverclock); + } + @NotNull @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java index b227f3942c2..d649a7d6fa7 100644 --- a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java @@ -167,4 +167,21 @@ private void performVentingAnimation(BlockPos machinePos, EnumFacing ventingSide 1.0f); } } + + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + int totalSteam = (int) (resultOverclock[0] * resultOverclock[1] / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(resultOverclock); + } } From f43a676b9dbfcaa78e66145eda768671ec6bb3be Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:34:21 -0600 Subject: [PATCH 073/168] Use drain/extract for Recipe#matches (#2358) --- .../java/gregtech/api/recipes/Recipe.java | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java index f52c3adc10e..d52be1bac09 100644 --- a/src/main/java/gregtech/api/recipes/Recipe.java +++ b/src/main/java/gregtech/api/recipes/Recipe.java @@ -191,8 +191,54 @@ public static Recipe trimRecipeOutputs(Recipe currentRecipe, RecipeMap recipe public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable inputs, IMultipleTankHandler fluidInputs) { - return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), - GTUtility.fluidHandlerToList(fluidInputs)); + Pair fluids = null; + Pair items = null; + + if (fluidInputs.getFluidTanks().size() > 0) { + fluids = matchesFluid(GTUtility.fluidHandlerToList(fluidInputs)); + if (!fluids.getKey()) { + return false; + } + } + + if (inputs.getSlots() > 0) { + items = matchesItems(GTUtility.itemHandlerToList(inputs)); + if (!items.getKey()) { + return false; + } + } + + if (consumeIfSuccessful) { + if (fluids != null) { + int[] fluidAmountInTank = fluids.getValue(); + var backedList = fluidInputs.getFluidTanks(); + + for (int i = 0; i < fluidAmountInTank.length; i++) { + var tank = backedList.get(i); + FluidStack fluidStack = tank.getFluid(); + int fluidAmount = fluidAmountInTank[i]; + + if (fluidStack == null || fluidStack.amount == fluidAmount) { + continue; + } + tank.drain(Math.abs(fluidAmount - fluidStack.amount), true); + } + } + if (items != null) { + int[] itemAmountInSlot = items.getValue(); + for (int i = 0; i < itemAmountInSlot.length; i++) { + ItemStack itemInSlot = inputs.getStackInSlot(i); + int itemAmount = itemAmountInSlot[i]; + + if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount) { + continue; + } + inputs.extractItem(i, Math.abs(itemAmount - itemInSlot.getCount()), false); + } + } + } + + return true; } /** From cf313f01c54bb87ae176f1d5221ae4086e8ab84f Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 5 Feb 2024 13:14:48 -0600 Subject: [PATCH 074/168] Fix part sharing tooltip missing on some parts (#2375) --- .../MetaTileEntityComputationHatch.java | 10 ++++++++++ .../MetaTileEntityDataAccessHatch.java | 7 ++++++- .../MetaTileEntityObjectHolder.java | 15 +++++++++++++++ .../MetaTileEntityOpticalDataHatch.java | 11 +++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java index 850ea3730be..ae41352ceb2 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java @@ -13,10 +13,13 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; @@ -166,4 +169,11 @@ public T getCapability(Capability capability, EnumFacing side) { } return super.getCapability(capability, side); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java index c925716144e..a50acc06ba0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java @@ -175,6 +175,11 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List } else { tooltip.add(I18n.format("gregtech.machine.data_access_hatch.tooltip.2", getInventorySize())); } + if (canPartShare()) { + tooltip.add(I18n.format("gregtech.universal.enabled")); + } else { + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } @NotNull @@ -199,7 +204,7 @@ public List getDataInfo() { @Override public boolean canPartShare() { - return false; + return isCreative; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java index 5658841fcda..efb526a0616 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java @@ -18,6 +18,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -25,12 +26,14 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -207,6 +210,18 @@ public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { heldItems.removeNotifiableMetaTileEntity(controllerBase); } + @Override + public boolean canPartShare() { + return false; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } + private class ObjectHolderHandler extends NotifiableItemStackHandler { public ObjectHolderHandler(MetaTileEntity metaTileEntity) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java index ca4d8d8000c..054cbccfd19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java @@ -14,16 +14,20 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; @@ -134,4 +138,11 @@ public MultiblockAbility getAbility() { public void registerAbilities(@NotNull List abilityList) { abilityList.add(this); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } From 26c341eef6cb8ef2885fccd810d483647327ec1d Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:00:35 +0000 Subject: [PATCH 075/168] re-enable sharing for laser hatches (#2376) --- .../multi/multiblockpart/MetaTileEntityLaserHatch.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java index 2f622588c7b..76acce75c33 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java @@ -72,11 +72,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - public boolean canPartShare() { - return false; - } - @Override public MultiblockAbility getAbility() { return isOutput ? MultiblockAbility.OUTPUT_LASER : MultiblockAbility.INPUT_LASER; @@ -114,7 +109,7 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_in_till", amperage)); } tooltip.add(I18n.format("gregtech.universal.tooltip.energy_storage_capacity", buffer.getEnergyCapacity())); - tooltip.add(I18n.format("gregtech.universal.disabled")); + tooltip.add(I18n.format("gregtech.universal.enabled")); } @NotNull From 0750ca5c8143a513ba2bd7f30efb35b2dea9ddb3 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:59:21 -0600 Subject: [PATCH 076/168] Config and API for tick acceleration blocking (#2381) --- .../api/metatileentity/MetaTileEntity.java | 18 +++++++++++++++ .../java/gregtech/common/ConfigHolder.java | 5 +++++ .../MetaTileEntityWorldAccelerator.java | 22 +++++++++---------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index b29f8485b00..b654a1dc397 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -49,6 +49,7 @@ import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Optional.Method; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -125,6 +126,7 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, protected boolean muffled = false; private int playSoundCooldown = 0; + private int lastTick = 0; public MetaTileEntity(ResourceLocation metaTileEntityId) { this.metaTileEntityId = metaTileEntityId; @@ -754,6 +756,13 @@ private void updateLightValue() { } public void update() { + if (!allowTickAcceleration()) { + int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); + if (currentTick == lastTick) { + return; + } + lastTick = currentTick; + } for (MTETrait mteTrait : this.mteTraits.values()) { if (shouldUpdate(mteTrait)) { mteTrait.update(); @@ -769,6 +778,15 @@ public void update() { } } + /** + * @return Whether this machine is allowed to be tick accelerated by external means. This does NOT + * apply to World Accelerators from GT, those will never work on machines. This refers to effects + * like Time in a Bottle, or Torcherino, or similar. + */ + public boolean allowTickAcceleration() { + return ConfigHolder.machines.allowTickAcceleration; + } + protected boolean shouldUpdate(MTETrait trait) { return true; } diff --git a/src/main/java/gregtech/common/ConfigHolder.java b/src/main/java/gregtech/common/ConfigHolder.java index 54863fecb57..290fb9f7d64 100644 --- a/src/main/java/gregtech/common/ConfigHolder.java +++ b/src/main/java/gregtech/common/ConfigHolder.java @@ -156,6 +156,11 @@ public static class MachineOptions { "Default: false" }) @Config.RequiresMcRestart public boolean highTierContent = false; + + @Config.Comment({ "Whether tick acceleration effects are allowed to affect GT machines.", + "This does NOT apply to the World Accelerator, but to external effects like Time in a Bottle.", + "Default: true" }) + public boolean allowTickAcceleration = true; } public static class WorldGenOptions { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java index 09c851400ce..861cdd4c9e9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java @@ -29,7 +29,6 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.FMLCommonHandler; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; @@ -57,7 +56,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme private boolean tileMode = false; private boolean isActive = false; private boolean isPaused = false; - private int lastTick; // Variables for Random Tick mode optimization // limit = ((tier - min) / (max - min)) * 2^tier @@ -67,7 +65,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme public MetaTileEntityWorldAccelerator(ResourceLocation metaTileEntityId, int tier) { super(metaTileEntityId, tier); - this.lastTick = 0; this.speed = (int) Math.pow(2, tier); this.successLimit = SUCCESS_LIMITS[tier - 1]; initializeInventory(); @@ -124,6 +121,11 @@ protected long getTEModeAmperage() { return 6L; } + @Override + public boolean allowTickAcceleration() { + return false; + } + @Override public void update() { super.update(); @@ -131,15 +133,11 @@ public void update() { if (isPaused && isActive) { setActive(false); } else if (!isPaused) { - int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); - if (currentTick != lastTick) { // Prevent other tick accelerators from accelerating us - lastTick = currentTick; - boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); - if (!wasSuccessful) { - setActive(false); - } else if (!isActive) { - setActive(true); - } + boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); + if (!wasSuccessful) { + setActive(false); + } else if (!isActive) { + setActive(true); } } } From 86dd52cb661b375baadca1c563093173d51fd921 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:36:00 -0500 Subject: [PATCH 077/168] fix material tree crash (#2382) --- src/main/java/gregtech/integration/jei/basic/MaterialTree.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java index 3babd634779..d919ab41597 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java @@ -73,7 +73,7 @@ public MaterialTree(Material material) { } List matFluidsStack = new ArrayList<>(); - if (material.hasProperty(PropertyKey.FLUID)) { + if (material.getFluid() != null) { matFluidsStack.add(material.getFluid(1000)); } this.fluidInputs.add(matFluidsStack); From d20820ed34829801771fe2d6a800faddb29e9677 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:52:44 -0500 Subject: [PATCH 078/168] fix #2382 (#2386) --- .../java/gregtech/integration/jei/basic/MaterialTree.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java index d919ab41597..82cc58d5dab 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java @@ -6,6 +6,7 @@ import gregtech.api.unification.ore.OrePrefix; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import com.google.common.collect.ImmutableList; @@ -73,8 +74,11 @@ public MaterialTree(Material material) { } List matFluidsStack = new ArrayList<>(); - if (material.getFluid() != null) { - matFluidsStack.add(material.getFluid(1000)); + if (material.hasProperty(PropertyKey.FLUID)) { + Fluid fluid = material.getFluid(); + if (fluid != null) { + matFluidsStack.add(new FluidStack(fluid, 1000)); + } } this.fluidInputs.add(matFluidsStack); From b816f00e4990ef91c32ff2499ae25e90a7342b53 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:59:12 -0600 Subject: [PATCH 079/168] Update build script version to 1707682661 (#2380) --- build.gradle | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index f4c0964bd89..8ea7b057a37 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1705076830 +//version: 1707682661 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -24,9 +24,9 @@ plugins { id 'eclipse' id 'maven-publish' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.28' - id 'net.darkhax.curseforgegradle' version '1.1.17' apply false - id 'com.modrinth.minotaur' version '2.8.6' apply false + id 'com.gtnewhorizons.retrofuturagradle' version '1.3.33' + id 'net.darkhax.curseforgegradle' version '1.1.18' apply false + id 'com.modrinth.minotaur' version '2.8.7' apply false id 'com.diffplug.spotless' version '6.13.0' apply false id 'com.palantir.git-version' version '3.0.0' apply false id 'com.github.johnrengelman.shadow' version '8.1.1' apply false @@ -446,6 +446,10 @@ repositories { name 'GTNH Maven' url 'https://nexus.gtnewhorizons.com/repository/public/' } + maven { + name 'GTCEu Maven' + url 'https://maven.gtceu.com' + } } if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { // need to add this here even if we did not above @@ -473,9 +477,25 @@ configurations { config.extendsFrom(shadowCompile) } } + + create("runtimeOnlyNonPublishable") { + description = "Runtime only dependencies that are not published alongside the jar" + canBeConsumed = false + canBeResolved = false + } + create("devOnlyNonPublishable") { + description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)" + canBeConsumed = false + canBeResolved = false + } + + compileOnly.extendsFrom(devOnlyNonPublishable) + runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable) + runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable) } -String mixinProviderSpec = 'zone.rong:mixinbooter:8.9' +String mixinProviderSpec = 'zone.rong:mixinbooter:9.1' dependencies { if (usesMixins.toBoolean()) { annotationProcessor 'org.ow2.asm:asm-debug-all:5.2' @@ -493,7 +513,7 @@ dependencies { transitive = false } } else if (forceEnableMixins.toBoolean()) { - runtimeOnly(mixinProviderSpec) + runtimeOnlyNonPublishable(mixinProviderSpec) } if (enableJUnit.toBoolean()) { @@ -503,8 +523,8 @@ dependencies { } if (enableModernJavaSyntax.toBoolean()) { - annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' - compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.1' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.1') { transitive = false } // workaround for https://github.com/bsideup/jabel/issues/174 @@ -513,8 +533,8 @@ dependencies { patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' // allow Jabel to work in tests - testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.0" - testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") { + testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.1" + testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.1") { transitive = false // We only care about the 1 annotation class } testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0" @@ -527,9 +547,13 @@ dependencies { } if (includeCommonDevEnvMods.toBoolean()) { - implementation 'mezz.jei:jei_1.12.2:4.16.1.302' - //noinspection DependencyNotationArgument - implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + if (!(modId.equals('jei'))) { + implementation 'mezz.jei:jei_1.12.2:4.16.1.302' + } + if (!(modId.equals('theoneprobe'))) { + //noinspection DependencyNotationArgument + implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + } } } From ee338111565e6ccad35e4a51fbc447b817aa8e26 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:03:05 -0600 Subject: [PATCH 080/168] Use GTCEu maven (#2379) --- dependencies.gradle | 92 ++++++++++++++++++++++++++------------------- gradle.properties | 2 +- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 19b3de56f63..7f2d35d408a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,57 +1,71 @@ //file:noinspection DependencyNotationArgument // TODO remove when fixed in RFG ^ /* - * Add your dependencies here. Common configurations: - * - implementation("group:name:version:classifier"): if you need this for internal implementation details of the mod. - * Available at compiletime and runtime for your environment. - * - * - compileOnlyApi("g:n:v:c"): if you need this for internal implementation details of the mod. - * Available at compiletime but not runtime for your environment. - * + * Add your dependencies here. Supported configurations: + * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod + * Available at runtime and compiletime for mods depending on this mod + * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API + * Available at runtime but not compiletime for mods depending on this mod + * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods + * Not available at all for mods depending on this mod, only visible at compiletime for this mod + * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod + * Available at compiletime but not runtime for mods depending on this mod + * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency + * Not available at all for mods depending on this mod, only visible at runtime for this mod + * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime, + * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing + * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime + * Available at runtime for mods depending on this mod * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry + * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main * - * - testCONFIG("g:n:v:c"): replace CONFIG by one of the above, same as above but for the test sources instead of main + * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name + * Requires you to enable usesShadowedDependencies in gradle.properties + * For more info, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/shadow.md * - * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed. + * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed, + * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful. + * + * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven, + * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file. * * To add a mod with CurseMaven, replace '("g:n:v:c")' in the above with 'rfg.deobf("curse.maven:project_slug-project_id:file_id")' - * Example: implementation rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:4527757") + * Example: devOnlyNonPublishable(rfg.deobf("curse.maven:top-245211:2667280")) + * + * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not. + * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published. * - * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph + * For more details, see https://docs.gradle.org/8.4/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - // Hard Dependencies - - // the CCL deobf jar uses very old MCP mappings, making it error at runtime in runClient/runServer - // therefore we manually deobf the regular jar - implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358 - - // Soft Dependencies - // Can change any of these from compileOnlyApi -> implementation to test them in-game. - - implementation "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684" - implementation rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - implementation rfg.deobf("curse.maven:groovyscript-687577:4905039") // GRS 0.7.0 - implementation rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + // Published dependencies + api("codechicken:codechickenlib:3.2.3.358") + api("com.cleanroommc:modularui:2.4.1") { transitive = false } + api("com.cleanroommc:groovyscript:0.7.3") { transitive = false } + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") + api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - compileOnlyApi rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 - compileOnlyApi "curse.maven:journeymap-32274:2916002" // Journeymap 5.7.1 - compileOnlyApi "curse.maven:voxelmap-225179:3029445" // VoxelMap 1.9.28 - compileOnlyApi "curse.maven:xaeros-263420:4516832" // Xaero's Minimap 23.4.1 - compileOnlyApi rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 - compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 - compileOnlyApi rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 - compileOnlyApi rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 + // Non-published dependencies + // Change any to devOnlyNonPublishable to test them in-game. + compileOnly("curse.maven:journeymap-32274:2916002") // Journeymap 5.7.1 + compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 + compileOnly("curse.maven:xaeros-263420:4516832") // Xaero's Minimap 23.4.1 + compileOnly rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 + compileOnly rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 + compileOnly rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 + compileOnly rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 + compileOnly rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - // runtimeOnly rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 - // runtimeOnly rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 - // runtimeOnly rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 - // runtimeOnly rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 } minecraft { @@ -59,7 +73,7 @@ minecraft { } configurations { - implementation { + compileOnly { // exclude GNU trove, FastUtil is superior and still updated exclude group: "net.sf.trove4j", module: "trove4j" // exclude javax.annotation from findbugs, jetbrains annotations are superior diff --git a/gradle.properties b/gradle.properties index d92a78eb1a7..4b8271aa57d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -145,7 +145,7 @@ noPublishedSources = false # For maven credentials: # Username is set with the 'MAVEN_USER' environment variable, default to "NONE" # Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE" -customMavenPublishUrl= +customMavenPublishUrl= https://maven.gtceu.com # The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any). # So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname' mavenArtifactGroup= From 4d18a9fa60aaa196d64997690724993df15898d6 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:26:20 -0600 Subject: [PATCH 081/168] Fix parallel overclocks using the wrong voltage for multiblocks (#2390) --- .../gregtech/api/capability/impl/MultiblockRecipeLogic.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 1ebb3e73c82..b27685c6987 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -434,6 +434,11 @@ public long getMaxVoltage() { } } + @Override + protected long getMaxParallelVoltage() { + return getMaximumOverclockVoltage(); + } + @Nullable @Override public RecipeMap getRecipeMap() { From 4588f6d1de12c77c6671583fc755d2d09fd4da52 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:37:35 -0600 Subject: [PATCH 082/168] Temporary hotfix for research ID lookup (#2391) --- .../gregtech/api/recipes/machines/RecipeMapAssemblyLine.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java index 0b9cd8099be..7a1fa3396a5 100644 --- a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java +++ b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java @@ -114,6 +114,10 @@ public boolean removeRecipe(@NotNull Recipe recipe) { @Override public void addDataStickEntry(@NotNull String researchId, @NotNull Recipe recipe) { + if (researchId.contains("xmetaitem.")) { + // save compatibility with an issue in 2.8.6, causing research IDs to change + addDataStickEntry(researchId.replace("xmetaitem.", "xitem.meta_item."), recipe); + } Collection collection = researchEntries.computeIfAbsent(researchId, (k) -> new ObjectOpenHashSet<>()); collection.add(recipe); } From f0c4edec82208f04d51f09a68dbee9b6643f320f Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:09:37 -0500 Subject: [PATCH 083/168] Use chestWood oredict for ULV and LV item buses (#2383) --- .../MetaTileEntityMachineRecipeLoader.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index 8d5775942e6..013e759001f 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -1,8 +1,12 @@ package gregtech.loaders.recipe; import gregtech.api.GTValues; +import gregtech.api.items.OreDictNames; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.Mods; @@ -18,7 +22,6 @@ import static gregtech.common.blocks.MetaBlocks.LD_FLUID_PIPE; import static gregtech.common.blocks.MetaBlocks.LD_ITEM_PIPE; import static gregtech.common.items.MetaItems.*; -import static gregtech.common.items.MetaItems.SENSOR_UV; import static gregtech.common.metatileentities.MetaTileEntities.*; public class MetaTileEntityMachineRecipeLoader { @@ -242,8 +245,8 @@ public static void init() { .duration(300).EUt(VA[EV]).buildAndRegister(); // Item Buses - registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], new ItemStack(Blocks.CHEST)); - registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], new ItemStack(Blocks.CHEST)); + registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], OreDictNames.chestWood.toString()); + registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], OreDictNames.chestWood.toString()); registerHatchBusRecipe(MV, ITEM_IMPORT_BUS[MV], ITEM_EXPORT_BUS[MV], BRONZE_CRATE.getStackForm()); registerHatchBusRecipe(HV, ITEM_IMPORT_BUS[HV], ITEM_EXPORT_BUS[HV], STEEL_CRATE.getStackForm()); registerHatchBusRecipe(EV, ITEM_IMPORT_BUS[EV], ITEM_EXPORT_BUS[EV], ALUMINIUM_CRATE.getStackForm()); @@ -1025,7 +1028,16 @@ public static void init() { } private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, MetaTileEntity outputBus, - ItemStack extra) { + Object extraInput) { + GTRecipeInput extra; + if (extraInput instanceof ItemStack stack) { + extra = new GTRecipeItemInput(stack); + } else if (extraInput instanceof String oreName) { + extra = new GTRecipeOreInput(oreName); + } else { + throw new IllegalArgumentException("extraInput must be ItemStack or GTRecipeInput"); + } + // Glue recipe for ULV and LV // 250L for ULV, 500L for LV if (tier <= GTValues.LV) { @@ -1114,29 +1126,18 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me } private static int getFluidAmount(int offsetTier) { - switch (offsetTier) { - case 0: - return 4; - case 1: - return 9; - case 2: - return 18; - case 3: - return 36; - case 4: - return 72; - case 5: - return 144; - case 6: - return 288; - case 7: - return 432; - case 8: - return 576; - case 9: - default: - return 720; - } + return switch (offsetTier) { + case 0 -> 4; + case 1 -> 9; + case 2 -> 18; + case 3 -> 36; + case 4 -> 72; + case 5 -> 144; + case 6 -> 288; + case 7 -> 432; + case 8 -> 576; + default -> 720; + }; } // TODO clean this up with a CraftingComponent rework From c70615dd2902384b28f768005816ea88580d20fe Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:14:55 -0600 Subject: [PATCH 084/168] add maven to GHA publish action --- .github/workflows/publish_project.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml index 2172ac6806e..69fb413604c 100644 --- a/.github/workflows/publish_project.yml +++ b/.github/workflows/publish_project.yml @@ -41,6 +41,12 @@ jobs: generate_release_notes: true fail_on_unmatched_files: true + - name: Publish to Maven + env: + MAVEN_USER: "${{ secrets.MAVEN_USER }}" + MAVEN:PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" + run: ./gradlew publish + - name: Publish to Curseforge env: CURSEFORGE_API_KEY: "${{ secrets.CURSEFORGE_API_KEY }}" From 820d0bc53b622a9846fea5d6c5a288ad22c974c7 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:21:42 -0600 Subject: [PATCH 085/168] cherrypick fix --- .../gregtech/common/blocks/explosive/BlockGTExplosive.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java index e18a97abbbf..e11a36f9cfe 100644 --- a/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java +++ b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java @@ -1,6 +1,6 @@ package gregtech.common.blocks.explosive; -import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.api.GregTechAPI; import gregtech.common.entities.EntityGTExplosive; import net.minecraft.block.Block; @@ -47,7 +47,7 @@ public BlockGTExplosive(Material materialIn, boolean canRedstoneActivate, boolea this.canRedstoneActivate = canRedstoneActivate; this.explodeOnMine = explodeOnMine; this.fuseLength = fuseLength; - setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); + setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); } protected abstract EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder); From fd7447371ad0a70e582823ede4eab4b14f007137 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:22:23 -0600 Subject: [PATCH 086/168] 2.8.7 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 4b8271aa57d..0f5fa43458d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.6-beta +modVersion = 2.8.7-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From f2a6d84737e42e1e5dc2ed69f9f3420f8fe90d68 Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:28:45 -0600 Subject: [PATCH 087/168] fix maven upload action --- .github/workflows/publish_project.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml index 69fb413604c..a6bb305d5bb 100644 --- a/.github/workflows/publish_project.yml +++ b/.github/workflows/publish_project.yml @@ -44,7 +44,7 @@ jobs: - name: Publish to Maven env: MAVEN_USER: "${{ secrets.MAVEN_USER }}" - MAVEN:PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" + MAVEN_PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" run: ./gradlew publish - name: Publish to Curseforge From 842477747cbaefcff5d1e0304c3fba059e64d588 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 2 Mar 2024 21:32:27 -0500 Subject: [PATCH 088/168] fix quantum tank not always fully reading custom data (#2396) (cherry picked from commit 675efe0712af3a4dcdae53e3075a6dd45fc0c9c9) --- .../storage/MetaTileEntityQuantumTank.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java index 6e27064a4e3..d6624d95823 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java @@ -11,7 +11,14 @@ import gregtech.api.cover.CoverRayTracer; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.FluidContainerSlotWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.PhantomTankWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.IFastRenderMetaTileEntity; import gregtech.api.metatileentity.ITieredMetaTileEntity; @@ -443,14 +450,16 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { try { this.fluidTank.setFluid(FluidStack.loadFluidStackFromNBT(buf.readCompoundTag())); } catch (IOException ignored) { - GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at " + this.getPos() + - " on a routine fluid update"); + GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at {} on a routine fluid update", + this.getPos()); } scheduleRenderUpdate(); } else if (dataId == UPDATE_FLUID_AMOUNT) { + // amount must always be read even if it cannot be used to ensure the reader index advances + int amount = buf.readInt(); FluidStack stack = fluidTank.getFluid(); if (stack != null) { - stack.amount = Math.min(buf.readInt(), fluidTank.getCapacity()); + stack.amount = Math.min(amount, fluidTank.getCapacity()); scheduleRenderUpdate(); } } else if (dataId == UPDATE_IS_VOIDING) { From 8810f75f6548ec70f1318e0a90f36487cbcf6810 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Sat, 2 Mar 2024 23:17:25 -0700 Subject: [PATCH 089/168] Fix NPE from facing being null when drawing grid overlays (#2401) (cherry picked from commit ae5ef986446366ccb7305bc946e5a01a7affaa92) --- src/main/java/gregtech/common/ToolEventHandlers.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index 65d407e9635..62195e49791 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -477,6 +477,8 @@ private static void drawGridOverlays(@NotNull AxisAlignedBB box) { @SideOnly(Side.CLIENT) private static void drawGridOverlays(EnumFacing facing, AxisAlignedBB box, Predicate test) { + if (facing == null) return; + Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); buffer.begin(3, DefaultVertexFormats.POSITION_COLOR); From d71f901683fc01a39a1aec0aaeb2543e6031de2b Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sun, 3 Mar 2024 02:08:27 -0700 Subject: [PATCH 090/168] Drain Tricorder energy only when in survival (#2402) (cherry picked from commit 74272b220806d2268f3d5d33443a0e8340ef9d3d) --- .../gregtech/common/items/behaviors/TricorderBehavior.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 344b97231d3..82a2f46c854 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -63,7 +63,9 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo List info = getScannerInfo(player, world, pos); if (player.isCreative() || drainEnergy(player.getHeldItem(hand), energyCost, true)) { - drainEnergy(player.getHeldItem(hand), energyCost, false); + if (!player.isCreative()) { + drainEnergy(player.getHeldItem(hand), energyCost, false); + } for (ITextComponent line : info) { player.sendMessage(line); } From a6ead71adc9ecb0906fe195e997e904777455daa Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:14:43 -0600 Subject: [PATCH 091/168] Advanced Stocking Input Bus + Advanced Stocking Input Hatch (#2367) (cherry picked from commit db174d2d802cbf7b51bfb9553fc7ec4921fec569) --- .../api/capability/GregtechDataCodes.java | 4 + .../java/gregtech/api/gui/GuiTextures.java | 6 + .../multiblock/IMultiblockPart.java | 3 + .../multiblock/MultiblockControllerBase.java | 2 +- .../RecipeMapMultiblockController.java | 1 + .../client/renderer/texture/Textures.java | 8 + .../gui/widget/appeng/AEConfigWidget.java | 45 +- .../widget/appeng/AEFluidConfigWidget.java | 40 +- .../gui/widget/appeng/AEItemConfigWidget.java | 40 +- .../gui/widget/appeng/slot/AEConfigSlot.java | 34 +- .../widget/appeng/slot/AEFluidConfigSlot.java | 91 +++- .../widget/appeng/slot/AEItemConfigSlot.java | 97 +++- .../gui/widget/appeng/slot/AmountSetSlot.java | 2 +- .../metatileentities/MetaTileEntities.java | 15 +- .../appeng/MetaTileEntityAEHostablePart.java | 93 ++-- .../appeng/MetaTileEntityMEInputBus.java | 424 +++++++----------- .../appeng/MetaTileEntityMEInputHatch.java | 318 ++++--------- .../appeng/MetaTileEntityMEOutputBus.java | 59 ++- .../appeng/MetaTileEntityMEOutputHatch.java | 63 ++- .../appeng/MetaTileEntityMEStockingBus.java | 414 +++++++++++++++++ .../appeng/MetaTileEntityMEStockingHatch.java | 375 ++++++++++++++++ .../appeng/slot/ExportOnlyAEFluidList.java | 64 +++ .../appeng/slot/ExportOnlyAEFluidSlot.java | 192 ++++++++ .../appeng/slot/ExportOnlyAEItemList.java | 126 ++++++ .../appeng/slot/ExportOnlyAEItemSlot.java | 138 ++++++ .../appeng/{ => slot}/ExportOnlyAESlot.java | 11 +- .../appeng/{ => slot}/IConfigurableSlot.java | 7 +- .../appeng/stack/WrappedItemStack.java | 10 +- .../MetaTileEntityMachineRecipeLoader.java | 19 + .../resources/assets/gregtech/lang/en_us.lang | 32 +- .../blocks/overlay/appeng/me_input_bus.png | Bin 154 -> 199 bytes .../overlay/appeng/me_input_bus_active.png | Bin 0 -> 196 bytes .../blocks/overlay/appeng/me_input_hatch.png | Bin 154 -> 199 bytes .../overlay/appeng/me_input_hatch_active.png | Bin 0 -> 196 bytes .../blocks/overlay/appeng/me_output_bus.png | Bin 154 -> 199 bytes .../overlay/appeng/me_output_bus_active.png | Bin 0 -> 195 bytes .../blocks/overlay/appeng/me_output_hatch.png | Bin 154 -> 199 bytes .../overlay/appeng/me_output_hatch_active.png | Bin 0 -> 195 bytes .../gregtech/textures/gui/base/slot_dark.png | Bin 0 -> 99 bytes .../textures/gui/widget/arrow_double.png | Bin 0 -> 215 bytes .../gui/widget/button_me_auto_pull.png | Bin 0 -> 273 bytes 41 files changed, 2004 insertions(+), 729 deletions(-) create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java rename src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/{ => slot}/ExportOnlyAESlot.java (94%) rename src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/{ => slot}/IConfigurableSlot.java (66%) create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png create mode 100644 src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index b8720654da1..e68c85e2d75 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -170,4 +170,8 @@ public static int assignId() { // Alarm public static final int UPDATE_SOUND = assignId(); public static final int UPDATE_RADIUS = assignId(); + + // ME Parts + public static final int UPDATE_AUTO_PULL = assignId(); + public static final int UPDATE_ONLINE_STATUS = assignId(); } diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index e2a19ec6dcb..3623508e678 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -46,6 +46,9 @@ public class GuiTextures { public static final TextureArea FLUID_TANK_OVERLAY = TextureArea .fullImage("textures/gui/base/fluid_tank_overlay.png"); public static final TextureArea SLOT = AdoptableTextureArea.fullImage("textures/gui/base/slot.png", 18, 18, 1, 1); + public static final TextureArea SLOT_DARK = AdoptableTextureArea.fullImage("textures/gui/base/slot_dark.png", 18, + 18, 1, 1); + @Deprecated // idek what this texture is public static final TextureArea SLOT_DARKENED = TextureArea.fullImage("textures/gui/base/darkened_slot.png"); public static final SteamTexture SLOT_STEAM = SteamTexture.fullImage("textures/gui/base/slot_%s.png"); public static final TextureArea TOGGLE_BUTTON_BACK = TextureArea @@ -504,6 +507,9 @@ public class GuiTextures { public static final TextureArea CONFIG_ARROW_DARK = TextureArea .fullImage("textures/gui/widget/config_arrow_dark.png"); public static final TextureArea SELECT_BOX = TextureArea.fullImage("textures/gui/widget/select_box.png"); + public static final TextureArea BUTTON_AUTO_PULL = TextureArea + .fullImage("textures/gui/widget/button_me_auto_pull.png"); + public static final TextureArea ARROW_DOUBLE = TextureArea.fullImage("textures/gui/widget/arrow_double.png"); // Fusion Reactor custom images public static final TextureArea FUSION_REACTOR_MK1_TITLE = TextureArea diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java index dc6cb0e5d28..520a36dcebb 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java @@ -11,4 +11,7 @@ public interface IMultiblockPart { default boolean canPartShare() { return true; } + + /** Called when distinct mode is toggled on the controller that this part is attached to */ + default void onDistinctChange(boolean newValue) {} } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java index 933ec7b1259..54b5bd45b5c 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java @@ -343,9 +343,9 @@ public void checkStructurePattern() { abilityPart.registerAbilities(abilityInstancesList); } } - parts.forEach(part -> part.addToMultiBlock(this)); this.multiblockParts.addAll(parts); this.multiblockAbilities.putAll(abilities); + parts.forEach(part -> part.addToMultiBlock(this)); this.structureFormed = true; writeCustomData(STRUCTURE_FORMED, buf -> buf.writeBoolean(true)); formStructure(context); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4301adbacce..d90c9b548db 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -246,6 +246,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { this.isDistinct = isDistinct; recipeMapWorkable.onDistinctChanged(); + getMultiblockParts().forEach(part -> part.onDistinctChange(isDistinct)); // mark buses as changed on distinct toggle if (this.isDistinct) { this.notifiedItemInputList.addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); diff --git a/src/main/java/gregtech/client/renderer/texture/Textures.java b/src/main/java/gregtech/client/renderer/texture/Textures.java index 09de1dbb6ef..3a6d2fcf315 100644 --- a/src/main/java/gregtech/client/renderer/texture/Textures.java +++ b/src/main/java/gregtech/client/renderer/texture/Textures.java @@ -487,10 +487,18 @@ public class Textures { public static final SimpleOverlayRenderer ME_OUTPUT_HATCH = new SimpleOverlayRenderer( "overlay/appeng/me_output_hatch"); + public static final SimpleOverlayRenderer ME_OUTPUT_HATCH_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_output_hatch_active"); public static final SimpleOverlayRenderer ME_INPUT_HATCH = new SimpleOverlayRenderer( "overlay/appeng/me_input_hatch"); + public static final SimpleOverlayRenderer ME_INPUT_HATCH_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_input_hatch_active"); public static final SimpleOverlayRenderer ME_OUTPUT_BUS = new SimpleOverlayRenderer("overlay/appeng/me_output_bus"); + public static final SimpleOverlayRenderer ME_OUTPUT_BUS_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_output_bus_active"); public static final SimpleOverlayRenderer ME_INPUT_BUS = new SimpleOverlayRenderer("overlay/appeng/me_input_bus"); + public static final SimpleOverlayRenderer ME_INPUT_BUS_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_input_bus_active"); public static final ResourceLocation ACE_CAPE_TEXTURE = gregtechId("textures/capes/acecape.png"); public static final ResourceLocation AGENDER_CAPE_TEXTURE = gregtechId("textures/capes/agendercape.png"); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java index 59005459893..1195fa8f34f 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java @@ -6,7 +6,7 @@ import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.slot.AEConfigSlot; import gregtech.common.gui.widget.appeng.slot.AmountSetSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import appeng.api.storage.data.IAEStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -26,26 +26,34 @@ public abstract class AEConfigWidget> extends AbstractWidg protected Int2ObjectMap> changeMap = new Int2ObjectOpenHashMap<>(); protected IConfigurableSlot[] displayList; protected AmountSetSlot amountSetWidget; + protected final boolean isStocking; protected final static int UPDATE_ID = 1000; - public AEConfigWidget(int x, int y, IConfigurableSlot[] config) { + public AEConfigWidget(int x, int y, IConfigurableSlot[] config, boolean isStocking) { super(new Position(x, y), new Size(config.length * 18, 18 * 2)); + this.isStocking = isStocking; this.config = config; this.init(); - this.amountSetWidget = new AmountSetSlot<>(80, -40, this); - this.addWidget(this.amountSetWidget); - this.addWidget(this.amountSetWidget.getText()); - this.amountSetWidget.setVisible(false); - this.amountSetWidget.getText().setVisible(false); + if (!isStocking()) { + this.amountSetWidget = new AmountSetSlot<>(80, -40, this); + this.addWidget(this.amountSetWidget); + this.addWidget(this.amountSetWidget.getText()); + this.amountSetWidget.setVisible(false); + this.amountSetWidget.getText().setVisible(false); + } } public void enableAmount(int slotIndex) { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(slotIndex); this.amountSetWidget.setVisible(true); this.amountSetWidget.getText().setVisible(true); } public void disableAmount() { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(-1); this.amountSetWidget.setVisible(false); this.amountSetWidget.getText().setVisible(false); @@ -53,22 +61,29 @@ public void disableAmount() { @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.amountSetWidget.isVisible()) { - if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { - return true; + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (!isStocking()) { + if (this.amountSetWidget.isVisible()) { + if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { + return true; + } } - } - for (Widget w : this.widgets) { - if (w instanceof AEConfigSlot) { - ((AEConfigSlot) w).setSelect(false); + for (Widget w : this.widgets) { + if (w instanceof AEConfigSlot) { + ((AEConfigSlot) w).setSelect(false); + } } + this.disableAmount(); } - this.disableAmount(); return super.mouseClicked(mouseX, mouseY, button); } abstract void init(); + public boolean isStocking() { + return isStocking; + } + @Override public void detectAndSendChanges() { super.detectAndSendChanges(); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java index 1599217290c..b5f709b0b86 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEFluidConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; import appeng.api.storage.data.IAEFluidStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEFluidStack} config - * @Date 2023/4/21-1:45 - */ public class AEFluidConfigWidget extends AEConfigWidget { - public AEFluidConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEFluidList fluidList; + + public AEFluidConfigWidget(int x, int y, ExportOnlyAEFluidList fluidList) { + super(x, y, fluidList.getInventory(), fluidList.isStocking()); + this.fluidList = fluidList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - this.cached[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - line = index / 8; - this.addWidget(new AEFluidConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEFluidSlot(); + this.cached[index] = new ExportOnlyAEFluidSlot(); + this.addWidget(new AEFluidConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(FluidStack stack) { + return fluidList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return fluidList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java index c3707d4afaf..0f2afe98235 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEItemConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import appeng.api.storage.data.IAEItemStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEItemStack} config - * @Date 2023/4/22-1:02 - */ public class AEItemConfigWidget extends AEConfigWidget { - public AEItemConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEItemList itemList; + + public AEItemConfigWidget(int x, int y, ExportOnlyAEItemList itemList) { + super(x, y, itemList.getInventory(), itemList.isStocking()); + this.itemList = itemList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - this.cached[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - line = index / 8; - this.addWidget(new AEItemConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEItemSlot(); + this.cached[index] = new ExportOnlyAEItemSlot(); + this.addWidget(new AEItemConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(ItemStack stack) { + return itemList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return itemList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java index ed1b9145bd7..d663340a451 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java @@ -5,7 +5,7 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; @@ -17,13 +17,9 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot - * @Date 2023/4/22-0:30 - */ public class AEConfigSlot> extends Widget implements IGhostIngredientTarget { + protected static final int DISPLAY_X_OFFSET = 18 * 5; protected AEConfigWidget parentWidget; protected int index; protected final static int REMOVE_ID = 1000; @@ -43,14 +39,24 @@ public void drawInForeground(int mouseX, int mouseY) { IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); if (slot.getConfig() == null && mouseOverConfig(mouseX, mouseY)) { List hoverStringList = new ArrayList<>(); - hoverStringList.add(I18n.format("gregtech.gui.config_slot")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.set")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.scroll")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.remove")); - drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + addHoverText(hoverStringList); + if (!hoverStringList.isEmpty()) { + drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + } } } + protected void addHoverText(List hoverText) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + if (!parentWidget.isStocking()) { + hoverText.add(I18n.format("gregtech.gui.config_slot.set")); + hoverText.add(I18n.format("gregtech.gui.config_slot.scroll")); + } else { + hoverText.add(I18n.format("gregtech.gui.config_slot.set_only")); + } + hoverText.add(I18n.format("gregtech.gui.config_slot.remove")); + } + public void setSelect(boolean val) { this.select = val; } @@ -62,11 +68,15 @@ protected boolean mouseOverConfig(int mouseX, int mouseY) { protected boolean mouseOverStock(int mouseX, int mouseY) { Position position = getPosition(); - return isMouseOver(position.x, position.y + 18, 18, 18, mouseX, mouseY); + return isMouseOver(position.x + DISPLAY_X_OFFSET, position.y, 18, 18, mouseX, mouseY); } @Override public List> getPhantomTargets(Object ingredient) { return Collections.emptyList(); } + + public AEConfigWidget getParentWidget() { + return parentWidget; + } } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java index b4ab7e87beb..2b852fdeb14 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java @@ -7,10 +7,11 @@ import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.RenderUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -34,27 +35,26 @@ import static gregtech.api.capability.GregtechDataCodes.LOAD_PHANTOM_FLUID_STACK_FROM_NBT; import static gregtech.api.util.GTUtility.getFluidFromContainer; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEFluidStack} - * @Date 2023/4/21-0:50 - */ public class AEFluidConfigSlot extends AEConfigSlot { - public AEFluidConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEFluidConfigSlot(int x, int y, AEFluidConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEFluidConfigWidget getParentWidget() { + return (AEFluidConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEFluidConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEFluidStack config = slot.getConfig(); IAEFluidStack stock = slot.getStock(); - GuiTextures.FLUID_SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.FLUID_SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -62,22 +62,35 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender int stackY = position.y + 1; if (config != null) { RenderUtil.drawFluidForGui(config.getFluidStack(), config.getFluidStack().amount, stackX, stackY, 17, 17); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { - RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX, stackY + 18, 17, - 17); + RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX + DISPLAY_X_OFFSET, + stackY, 17, 17); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + } else { + GuiTextures.FLUID_SLOT.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); @@ -107,13 +120,31 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEFluidConfigWidget pw = getParentWidget(); + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + this.parentWidget.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack hold = this.gui.entityPlayer.inventory.getItemStack(); @@ -125,8 +156,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { buf.writeVarInt(fluid.amount); }); } - this.parentWidget.enableAmount(this.index); - this.select = true; + + if (!pw.isStocking()) { + this.parentWidget.enableAmount(this.index); + this.select = true; + } } return true; } @@ -145,6 +179,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { FluidStack fluid = FluidRegistry.getFluidStack(buffer.readString(Integer.MAX_VALUE / 16), buffer.readVarInt()); + if (!isFluidValidForSlot(fluid)) return; slot.setConfig(WrappedFluidStack.fromFluidStack(fluid)); this.parentWidget.enableAmount(this.index); if (fluid != null) { @@ -198,13 +233,20 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + private boolean isFluidValidForSlot(FluidStack stack) { + if (stack == null) return true; + AEFluidConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (getFluidFromContainer(ingredient) == null) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -227,9 +269,10 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java index 02cad40272b..3dff4140249 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java @@ -5,10 +5,11 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.relauncher.Side; @@ -24,27 +25,26 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEItemStack} - * @Date 2023/4/22-0:48 - */ public class AEItemConfigSlot extends AEConfigSlot { - public AEItemConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEItemConfigSlot(int x, int y, AEItemConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEItemConfigWidget getParentWidget() { + return (AEItemConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEItemConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEItemStack config = slot.getConfig(); IAEItemStack stock = slot.getStock(); - GuiTextures.SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW_DARK.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -54,28 +54,43 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender ItemStack stack = config.createItemStack(); stack.setCount(1); drawItemStack(stack, stackX, stackY, null); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + // Only draw the config amount if not stocking, as its meaningless when stocking + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { ItemStack stack = stock.createItemStack(); stack.setCount(1); - drawItemStack(stack, stackX, stackY + 18, null); + drawItemStack(stack, stackX + DISPLAY_X_OFFSET, stackY, null); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } else { + GuiTextures.SLOT.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW_DARK.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); IAEItemStack item = null; - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = this.getParentWidget().getDisplay(this.index); if (mouseOverConfig(mouseX, mouseY)) { item = slot.getConfig(); } else if (mouseOverStock(mouseX, mouseY)) { @@ -86,22 +101,45 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEItemConfigWidget pw = getParentWidget(); + // don't allow manual interaction with config slots when auto pull is enabled + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + pw.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack item = this.gui.entityPlayer.inventory.getItemStack(); if (!item.isEmpty()) { writeClientAction(UPDATE_ID, buf -> buf.writeItemStack(item)); + return true; + } + + if (!pw.isStocking()) { + pw.enableAmount(this.index); + this.select = true; } - this.parentWidget.enableAmount(this.index); - this.select = true; } return true; } @@ -120,6 +158,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { try { ItemStack item = buffer.readItemStack(); + if (!isItemValidForSlot(item)) return; slot.setConfig(WrappedItemStack.fromItemStack(item)); this.parentWidget.enableAmount(this.index); if (!item.isEmpty()) { @@ -157,13 +196,21 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + // Method for server-side validation of an attempted new configured item + private boolean isItemValidForSlot(ItemStack stack) { + if (stack == null || stack.isEmpty()) return true; + AEItemConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (!(ingredient instanceof ItemStack)) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -183,9 +230,11 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + // Only allow the amount scrolling if not stocking, as amount is useless for stocking + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java index ccec8521dd7..35063d5638b 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java @@ -6,7 +6,7 @@ import gregtech.api.gui.widgets.TextFieldWidget2; import gregtech.api.util.Position; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.network.PacketBuffer; diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 156c0a63f81..4e57f3c5b93 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -33,6 +33,8 @@ import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputBus; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingHatch; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCABridge; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCAComputation; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCACooler; @@ -286,6 +288,8 @@ public class MetaTileEntities { public static MetaTileEntity ITEM_EXPORT_BUS_ME; public static MetaTileEntity FLUID_IMPORT_HATCH_ME; public static MetaTileEntity ITEM_IMPORT_BUS_ME; + public static MetaTileEntity STOCKING_BUS_ME; + public static MetaTileEntity STOCKING_HATCH_ME; public static MetaTileEntityLDItemEndpoint LONG_DIST_ITEM_ENDPOINT; public static MetaTileEntityLDFluidEndpoint LONG_DIST_FLUID_ENDPOINT; public static MetaTileEntityAlarm ALARM; @@ -1047,7 +1051,7 @@ public static void init() { // IDs 1730-1744 are taken by 4A <-> 16A Transformers. They are grouped with other transformers for // organization. - // ME Hatches, IDs 1745-1748 + // ME Hatches, IDs 1745-1748, 1752-1756 if (Mods.AppliedEnergistics2.isModLoaded()) { FLUID_EXPORT_HATCH_ME = registerMetaTileEntity(1745, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); @@ -1057,6 +1061,13 @@ public static void init() { new MetaTileEntityMEInputHatch(gregtechId("me_import_fluid_hatch"))); ITEM_IMPORT_BUS_ME = registerMetaTileEntity(1748, new MetaTileEntityMEInputBus(gregtechId("me_import_item_bus"))); + STOCKING_BUS_ME = registerMetaTileEntity(1752, + new MetaTileEntityMEStockingBus(gregtechId("me_stocking_item_bus"))); + STOCKING_HATCH_ME = registerMetaTileEntity(1753, + new MetaTileEntityMEStockingHatch(gregtechId("me_stocking_fluid_hatch"))); + // 1754: Crafting Input Bus + // 1755: Crafting Input Buffer + // 1756: Crafting Input Slave } LONG_DIST_ITEM_ENDPOINT = registerMetaTileEntity(1749, @@ -1067,6 +1078,8 @@ public static void init() { // Alarm, ID 1751 ALARM = registerMetaTileEntity(1751, new MetaTileEntityAlarm(gregtechId("alarm"))); + // IDs 1752-1756 are taken by AE2 parts + // Multi-Fluid Hatches, IDs 1190, 1191, 1205, 1206, 1780-1799 // EV hatches separate because of old names/IDs QUADRUPLE_IMPORT_HATCH[0] = registerMetaTileEntity(1190, diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java index 7f470e4d0ff..1c8f73e6837 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java @@ -1,10 +1,6 @@ package gregtech.common.metatileentities.multi.multiblockpart.appeng; -import gregtech.api.GTValues; import gregtech.api.capability.IControllable; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.client.renderer.ICubeRenderer; -import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; @@ -19,13 +15,12 @@ import appeng.api.networking.GridFlags; import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionSource; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.IStorageChannel; -import appeng.api.storage.channels.IFluidStorageChannel; -import appeng.api.storage.channels.IItemStorageChannel; -import appeng.api.storage.data.IAEFluidStack; -import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; +import appeng.me.GridAccessException; import appeng.me.helpers.AENetworkProxy; import appeng.me.helpers.BaseActionSource; import appeng.me.helpers.IGridProxyable; @@ -36,28 +31,21 @@ import java.io.IOException; import java.util.EnumSet; -/** - * @Author GlodBlock - * @Description It can connect to ME network. - * @Date 2023/4/18-23:17 - */ -public abstract class MetaTileEntityAEHostablePart extends MetaTileEntityMultiblockNotifiablePart - implements IControllable { +import static gregtech.api.capability.GregtechDataCodes.UPDATE_ONLINE_STATUS; - protected static final IStorageChannel ITEM_NET = AEApi.instance().storage() - .getStorageChannel(IItemStorageChannel.class); - protected static final IStorageChannel FLUID_NET = AEApi.instance().storage() - .getStorageChannel(IFluidStorageChannel.class); +public abstract class MetaTileEntityAEHostablePart> extends MetaTileEntityMultiblockNotifiablePart + implements IControllable { - private final static int ME_UPDATE_INTERVAL = ConfigHolder.compat.ae2.updateIntervals; + private final Class> storageChannel; private AENetworkProxy aeProxy; private int meUpdateTick; protected boolean isOnline; - private final static int ONLINE_ID = 6666; - public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { + public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch, + Class> storageChannel) { super(metaTileEntityId, tier, isExportHatch); this.meUpdateTick = 0; + this.storageChannel = storageChannel; } @Override @@ -73,9 +61,7 @@ public void update() { * So there is no need to drop them. */ @Override - public void clearMachineInventory(NonNullList itemBuffer) { - // NO-OP - } + public void clearMachineInventory(NonNullList itemBuffer) {} @Override public void writeInitialSyncData(PacketBuffer buf) { @@ -114,24 +100,9 @@ public void receiveInitialSyncData(PacketBuffer buf) { @Override public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == ONLINE_ID) { + if (dataId == UPDATE_ONLINE_STATUS) { this.isOnline = buf.readBoolean(); - } - } - - @Override - public ICubeRenderer getBaseTexture() { - MultiblockControllerBase controller = getController(); - if (controller != null) { - return this.hatchTexture = controller.getBaseTexture(this); - } else if (this.hatchTexture != null) { - if (hatchTexture != Textures.getInactiveTexture(hatchTexture)) { - return this.hatchTexture = Textures.getInactiveTexture(hatchTexture); - } - return this.hatchTexture; - } else { - // Always display as EV casing - return Textures.VOLTAGE_CASINGS[GTValues.EV]; + scheduleRenderUpdate(); } } @@ -165,9 +136,7 @@ public void setFrontFacing(EnumFacing frontFacing) { } @Override - public void gridChanged() { - // NO-OP - } + public void gridChanged() {} /** * Update me network connection status. @@ -180,26 +149,27 @@ public boolean updateMEStatus() { } else { this.isOnline = false; } - writeCustomData(ONLINE_ID, buf -> buf.writeBoolean(this.isOnline)); + if (!getWorld().isRemote) { + writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(this.isOnline)); + } return this.isOnline; } protected boolean shouldSyncME() { - return this.meUpdateTick % ME_UPDATE_INTERVAL == 0; + return this.meUpdateTick % ConfigHolder.compat.ae2.updateIntervals == 0; } protected IActionSource getActionSource() { - if (this.getHolder() instanceof IActionHost) { - return new MachineSource((IActionHost) this.getHolder()); + if (this.getHolder() instanceof IActionHost holder) { + return new MachineSource(holder); } return new BaseActionSource(); } @Nullable private AENetworkProxy createProxy() { - if (this.getHolder() instanceof IGridProxyable) { - AENetworkProxy proxy = new AENetworkProxy((IGridProxyable) this.getHolder(), "mte_proxy", - this.getStackForm(), true); + if (this.getHolder() instanceof IGridProxyable holder) { + AENetworkProxy proxy = new AENetworkProxy(holder, "mte_proxy", this.getStackForm(), true); proxy.setFlags(GridFlags.REQUIRE_CHANNEL); proxy.setIdlePowerUsage(ConfigHolder.compat.ae2.meHatchEnergyUsage); proxy.setValidSides(EnumSet.of(this.getFrontFacing())); @@ -207,4 +177,23 @@ private AENetworkProxy createProxy() { } return null; } + + @NotNull + protected IStorageChannel getStorageChannel() { + return AEApi.instance().storage().getStorageChannel(storageChannel); + } + + @Nullable + protected IMEMonitor getMonitor() { + AENetworkProxy proxy = getProxy(); + if (proxy == null) return null; + + IStorageChannel channel = getStorageChannel(); + + try { + return proxy.getStorage().getInventory(channel); + } catch (GridAccessException ignored) { + return null; + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 18a81b7df3d..1076de705e9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -3,15 +3,25 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IGhostSlotConfigurable; +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.GhostCircuitSlotWidget; +import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; import net.minecraft.client.resources.I18n; @@ -23,117 +33,160 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; -import java.util.function.Consumer; -/** - * @Author GlodBlock - * @Description The Input Bus that can auto fetch item ME storage network. - * @Date 2023/4/22-13:34 - */ -public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { +public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart + implements IMultiblockAbilityPart, + IGhostSlotConfigurable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEItemList aeItemHandler; + private boolean workingEnabled = true; + protected ExportOnlyAEItemList aeItemHandler; + private GhostCircuitItemStackHandler circuitInventory; + private NotifiableItemStackHandler extraSlotInventory; + private ItemHandlerList actualImportItems; public MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IItemStorageChannel.class); + } + + protected ExportOnlyAEItemList getAEItemHandler() { + if (aeItemHandler == null) { + aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); + } + return aeItemHandler; } @Override protected void initializeInventory() { - this.aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); super.initializeInventory(); - } - - protected IItemHandlerModifiable createImportItemHandler() { - return this.aeItemHandler; + this.aeItemHandler = getAEItemHandler(); + this.circuitInventory = new GhostCircuitItemStackHandler(this); + this.circuitInventory.addNotifiableMetaTileEntity(this); + this.extraSlotInventory = new NotifiableItemStackHandler(this, 1, this, false); + this.extraSlotInventory.addNotifiableMetaTileEntity(this); + this.actualImportItems = new ItemHandlerList( + Arrays.asList(this.aeItemHandler, this.circuitInventory, this.extraSlotInventory)); + this.importItems = this.actualImportItems; } public IItemHandlerModifiable getImportItems() { - this.importItems = this.aeItemHandler; - return super.getImportItems(); + return this.actualImportItems; } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - // Try to clear the wrong item - IAEItemStack exceedItem = aeSlot.exceedStack(); - if (exceedItem != null) { - long total = exceedItem.getStackSize(); - IAEItemStack notInserted = aeNetwork.injectItems(exceedItem, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); - continue; - } else { - aeSlot.extractItem(0, (int) total, false); - } - } - // Fill it - IAEItemStack reqItem = aeSlot.requestStack(); - if (reqItem != null) { - IAEItemStack extracted = aeNetwork.extractItems(reqItem, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeSlot.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && updateMEStatus() && shouldSyncME()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - IAEItemStack stock = aeSlot.stock; - if (stock instanceof WrappedItemStack) { - stock = ((WrappedItemStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + // Try to clear the wrong item + IAEItemStack exceedItem = aeSlot.exceedStack(); + if (exceedItem != null) { + long total = exceedItem.getStackSize(); + IAEItemStack notInserted = monitor.injectItems(exceedItem, Actionable.MODULATE, this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); + continue; + } else { + aeSlot.extractItem(0, (int) total, false); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEItemStack reqItem = aeSlot.requestStack(); + if (reqItem != null) { + IAEItemStack extracted = monitor.extractItems(reqItem, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeSlot.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + IAEItemStack stock = aeSlot.getStock(); + if (stock instanceof WrappedItemStack) { + stock = ((WrappedItemStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { - return new MetaTileEntityMEInputBus(this.metaTileEntityId); + return new MetaTileEntityMEInputBus(metaTileEntityId); + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.addNotifiableMetaTileEntity(controllerBase); + notifiable.addToNotifiedList(this, handler, false); + } + } } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + super.removeFromMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.removeNotifiableMetaTileEntity(controllerBase); + } + } + } + + @Override + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -141,13 +194,37 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEItemConfigWidget(16, 25, this.aeItemHandler.inventory)); + builder.widget(new AEItemConfigWidget(7, 25, this.getAEItemHandler())); + + // Ghost circuit slot + SlotWidget circuitSlot = new GhostCircuitSlotWidget(circuitInventory, 0, 7 + 18 * 4, 25 + 18 * 3) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.INT_CIRCUIT_OVERLAY); + builder.widget(circuitSlot.setConsumer(w -> { + String configString; + if (circuitInventory == null || + circuitInventory.getCircuitValue() == GhostCircuitItemStackHandler.NO_CONFIG) { + configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value") + .getFormattedText(); + } else { + configString = String.valueOf(circuitInventory.getCircuitValue()); + } + + w.setTooltipText("gregtech.gui.configurator_slot.tooltip", configString); + })); + + // Extra slot + builder.widget(new SlotWidget(extraSlotInventory, 0, 7 + 18 * 4, 25 + 18 * 2) + .setBackgroundTexture(GuiTextures.SLOT) + .setTooltipText("gregtech.gui.me_bus.extra_slot")); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -190,13 +267,16 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList slots = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEItem slot = this.aeItemHandler.inventory[i]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[i]; NBTTagCompound slotTag = new NBTTagCompound(); slotTag.setInteger("slot", i); slotTag.setTag("stack", slot.serializeNBT()); slots.appendTag(slotTag); } data.setTag(ITEM_BUFFER_TAG, slots); + this.circuitInventory.write(data); + // Extra slot inventory + GTUtility.writeItems(this.extraSlotInventory, "ExtraInventory", data); return data; } @@ -210,10 +290,12 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList slots = (NBTTagList) data.getTag(ITEM_BUFFER_TAG); for (NBTBase nbtBase : slots) { NBTTagCompound slotTag = (NBTTagCompound) nbtBase; - ExportOnlyAEItem slot = this.aeItemHandler.inventory[slotTag.getInteger("slot")]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[slotTag.getInteger("slot")]; slot.deserializeNBT(slotTag.getCompoundTag("stack")); } } + this.circuitInventory.read(data); + GTUtility.readItems(this.extraSlotInventory, "ExtraInventory", data); this.importItems = createImportItemHandler(); } @@ -221,7 +303,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -231,6 +317,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -241,197 +328,22 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.add(this.aeItemHandler); + list.add(this.actualImportItems); } - private static class ExportOnlyAEItemList extends NotifiableItemStackHandler { - - ExportOnlyAEItem[] inventory; - - public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { - super(holder, slots, entityToNotify, false); - this.inventory = new ExportOnlyAEItem[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.inventory[i] = new ExportOnlyAEItem(null, null); - } - for (ExportOnlyAEItem slot : this.inventory) { - slot.trigger = this::onContentsChanged; - } - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - for (int index = 0; index < CONFIG_SIZE; index++) { - if (nbt.hasKey("#" + index)) { - NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); - this.inventory[index].deserializeNBT(slotTag); - } - } - } - - @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound nbt = new NBTTagCompound(); - for (int index = 0; index < CONFIG_SIZE; index++) { - NBTTagCompound slot = this.inventory[index].serializeNBT(); - nbt.setTag("#" + index, slot); - } - return nbt; - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP - } - - @Override - public int getSlots() { - return MetaTileEntityMEInputBus.CONFIG_SIZE; - } - - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].getStackInSlot(0); - } - return ItemStack.EMPTY; - } - - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; - } - - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].extractItem(0, amount, simulate); - } - return ItemStack.EMPTY; - } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; - } - - @Override - protected int getStackLimit(int slot, @NotNull ItemStack stack) { - return Integer.MAX_VALUE; - } + @Override + public boolean hasGhostCircuitInventory() { + return true; } - public static class ExportOnlyAEItem extends ExportOnlyAESlot implements IItemHandlerModifiable { - - private Consumer trigger; - - public ExportOnlyAEItem(IAEItemStack config, IAEItemStack stock) { - super(config, stock); - } - - public ExportOnlyAEItem() { - super(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Override - public ExportOnlyAEItem copy() { - return new ExportOnlyAEItem( - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy()); - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP - } - - @Override - public int getSlots() { - return 1; - } - - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot == 0 && this.stock != null) { - return this.stock.getDefinition(); - } - return ItemStack.EMPTY; - } - - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; - } - - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot == 0 && this.stock != null) { - int extracted = (int) Math.min(this.stock.getStackSize(), amount); - ItemStack result = this.stock.createItemStack(); - result.setCount(extracted); - if (!simulate) { - this.stock.decStackSize(extracted); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - } - if (this.trigger != null) { - this.trigger.accept(0); - } - return result; - } - return ItemStack.EMPTY; - } - - @Override - public IAEItemStack requestStack() { - IAEItemStack result = super.requestStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEItemStack exceedStack() { - IAEItemStack result = super.exceedStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEItemStack stack) { - if (this.stock == null) { - this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); - } else { - this.stock.add(stack); - } - this.trigger.accept(0); + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory.getCircuitValue() == config) { + return; } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index 9a6dfa4f6aa..c864cecff64 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -3,16 +3,18 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.client.resources.I18n; @@ -26,120 +28,126 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.FluidTankProperties; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidTankProperties; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * @Author GlodBlock - * @Description The Input Hatch that can auto fetch fluid ME storage network. - * @Date 2023/4/20-21:21 - */ -public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEFluid[] aeFluidTanks; + private boolean workingEnabled = true; + protected ExportOnlyAEFluidList aeFluidHandler; public MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IFluidStorageChannel.class); + } + + protected ExportOnlyAEFluidList getAEFluidHandler() { + if (aeFluidHandler == null) { + aeFluidHandler = new ExportOnlyAEFluidList(this, CONFIG_SIZE, this.getController()); + } + return aeFluidHandler; } @Override protected void initializeInventory() { - this.aeFluidTanks = new ExportOnlyAEFluid[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.aeFluidTanks[i] = new ExportOnlyAEFluid(this, null, null, this.getController()); - } + getAEFluidHandler(); // initialize it super.initializeInventory(); } @Override protected FluidTankList createImportFluidHandler() { - return new FluidTankList(false, this.aeFluidTanks); + return new FluidTankList(false, getAEFluidHandler().getInventory()); } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - // Try to clear the wrong fluid - IAEFluidStack exceedFluid = aeTank.exceedStack(); - if (exceedFluid != null) { - long total = exceedFluid.getStackSize(); - IAEFluidStack notInserted = aeNetwork.injectItems(exceedFluid, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeTank.drain((int) (total - notInserted.getStackSize()), true); - continue; - } else { - aeTank.drain((int) total, true); - } - } - // Fill it - IAEFluidStack reqFluid = aeTank.requestStack(); - if (reqFluid != null) { - IAEFluidStack extracted = aeNetwork.extractItems(reqFluid, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeTank.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - IAEFluidStack stock = aeTank.stock; - if (stock instanceof WrappedFluidStack) { - stock = ((WrappedFluidStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + // Try to clear the wrong fluid + IAEFluidStack exceedFluid = aeTank.exceedStack(); + if (exceedFluid != null) { + long total = exceedFluid.getStackSize(); + IAEFluidStack notInserted = monitor.injectItems(exceedFluid, Actionable.MODULATE, + this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeTank.drain((int) (total - notInserted.getStackSize()), true); + continue; + } else { + aeTank.drain((int) total, true); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEFluidStack reqFluid = aeTank.requestStack(); + if (reqFluid != null) { + IAEFluidStack extracted = monitor.extractItems(reqFluid, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeTank.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + IAEFluidStack stock = aeTank.getStock(); + if (stock instanceof WrappedFluidStack) { + stock = ((WrappedFluidStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { return new MetaTileEntityMEInputHatch(this.metaTileEntityId); } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -147,13 +155,21 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEFluidConfigWidget(16, 25, this.aeFluidTanks)); + builder.widget(new AEFluidConfigWidget(7, 25, this.getAEFluidHandler())); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); + + // GT Logo, cause there's some free real estate + builder.widget(new ImageWidget(7 + 18 * 4, 25 + 18 * 3, 17, 17, + GTValues.XMAS.get() ? GuiTextures.GREGTECH_LOGO_XMAS : GuiTextures.GREGTECH_LOGO) + .setIgnoreColor(true)); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -196,7 +212,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList tanks = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEFluid tank = this.aeFluidTanks[i]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[i]; NBTTagCompound tankTag = new NBTTagCompound(); tankTag.setInteger("slot", i); tankTag.setTag("tank", tank.serializeNBT()); @@ -216,7 +232,7 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList tanks = (NBTTagList) data.getTag(FLUID_BUFFER_TAG); for (NBTBase nbtBase : tanks) { NBTTagCompound tankTag = (NBTTagCompound) nbtBase; - ExportOnlyAEFluid tank = this.aeFluidTanks[tankTag.getInteger("slot")]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[tankTag.getInteger("slot")]; tank.deserializeNBT(tankTag.getCompoundTag("tank")); } } @@ -226,7 +242,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -236,6 +256,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -246,157 +267,6 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.addAll(Arrays.asList(this.aeFluidTanks)); - } - - public static class ExportOnlyAEFluid extends ExportOnlyAESlot - implements IFluidTank, INotifiableHandler, IFluidHandler { - - private final List notifiableEntities = new ArrayList<>(); - private MetaTileEntity holder; - - public ExportOnlyAEFluid(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { - super(config, stock); - this.holder = holder; - this.notifiableEntities.add(mte); - } - - public ExportOnlyAEFluid() { - super(); - } - - @Override - public IAEFluidStack requestStack() { - IAEFluidStack result = super.requestStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEFluidStack exceedStack() { - IAEFluidStack result = super.exceedStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEFluidStack stack) { - if (this.stock == null) { - this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); - } else { - this.stock.add(stack); - } - trigger(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Nullable - @Override - public FluidStack getFluid() { - if (this.stock != null && this.stock instanceof WrappedFluidStack) { - return ((WrappedFluidStack) this.stock).getDelegate(); - } - return null; - } - - @Override - public int getFluidAmount() { - return this.stock != null ? (int) this.stock.getStackSize() : 0; - } - - @Override - public int getCapacity() { - // Its capacity is always 0. - return 0; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(this); - } - - @Override - public IFluidTankProperties[] getTankProperties() { - return new IFluidTankProperties[] { - new FluidTankProperties(this.getFluid(), 0) - }; - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - return 0; - } - - @Nullable - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { - return this.drain(resource.amount, doDrain); - } - return null; - } - - @Nullable - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - if (this.stock == null) { - return null; - } - int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); - FluidStack result = new FluidStack(this.stock.getFluid(), drained); - if (doDrain) { - this.stock.decStackSize(drained); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - trigger(); - } - return result; - } - - @Override - public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.add(metaTileEntity); - } - - @Override - public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.remove(metaTileEntity); - } - - private void trigger() { - for (MetaTileEntity metaTileEntity : this.notifiableEntities) { - if (metaTileEntity != null && metaTileEntity.isValid()) { - this.addToNotifiedList(metaTileEntity, this, false); - } - } - if (holder != null) { - holder.markDirty(); - } - } - - @Override - public ExportOnlyAEFluid copy() { - return new ExportOnlyAEFluid( - this.holder, - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy(), - null); - } + list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java index 92277985603..853321014f9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java @@ -30,9 +30,9 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; -import appeng.me.GridAccessException; import appeng.util.item.AEItemStack; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; @@ -43,22 +43,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Bus that can directly send its contents to ME storage network. - * @Date 2023/4/19-20:37 - */ -public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String ITEM_BUFFER_TAG = "ItemBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableItemList internalBuffer; public MetaTileEntityMEOutputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IItemStorageChannel.class); } @Override @@ -70,21 +64,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (IAEItemStack item : this.internalBuffer) { - IAEItemStack notInserted = aeNetwork.injectItems(item.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - item.setStackSize(notInserted.getStackSize()); - } else { - item.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && this.updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEItemStack item : this.internalBuffer) { + IAEItemStack notInserted = monitor.injectItems(item.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + item.setStackSize(notInserted.getStackSize()); + } else { + item.reset(); } } } @@ -92,12 +83,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); + IMEMonitor monitor = getMonitor(); + if (monitor != null) { for (IAEItemStack item : this.internalBuffer) { - aeNetwork.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); + monitor.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); } - } catch (GridAccessException ignore) {} + } super.onRemoval(); } @@ -115,7 +106,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEItemGridWidget(10, 35, 3, this.internalBuffer)); @@ -180,7 +171,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -190,7 +185,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java index c19e7e1bb51..f22c489909b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java @@ -32,10 +32,10 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IItemList; import appeng.fluids.util.AEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; @@ -45,22 +45,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Hatch that can directly send its contents to ME storage network. - * @Date 2023/4/19-1:18 - */ -public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String FLUID_BUFFER_TAG = "FluidBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableFluidList internalBuffer; public MetaTileEntityMEOutputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IFluidStorageChannel.class); } @Override @@ -72,21 +66,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - IAEFluidStack notInserted = aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - fluid.setStackSize(notInserted.getStackSize()); - } else { - fluid.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + IAEFluidStack notInserted = monitor.injectItems(fluid.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + fluid.setStackSize(notInserted.getStackSize()); + } else { + fluid.reset(); } } } @@ -94,12 +85,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); - } - } catch (GridAccessException ignore) {} + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + monitor.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); + } super.onRemoval(); } @@ -117,7 +108,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEFluidGridWidget(10, 35, 3, this.internalBuffer)); @@ -182,7 +173,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -192,7 +187,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java new file mode 100644 index 00000000000..99928574f82 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -0,0 +1,414 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingBus extends MetaTileEntityMEInputBus { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingBus(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingBus(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingItemList getAEItemHandler() { + if (this.aeItemHandler == null) { + this.aeItemHandler = new ExportOnlyAEStockingItemList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingItemList) this.aeItemHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + } + + // Update the visual display for the fake items. This also is important for the item handler's + // getStackInSlot() method, as it uses the cached items set here. + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingItemSlot slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEItemStack request; + if (slot.getConfig() instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEItemStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + // ensure that no other stocking bus on this multiblock is configured to hold the same item. + // that we have in our own bus. + this.autoPullTest = stack -> !this.testConfiguredInOtherBus(stack); + // also ensure that our current config is valid given other inputs + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + // block auto-pull from working when not in a formed multiblock + this.autoPullTest = $ -> false; + if (this.autoPull) { + // may as well clear if we are auto-pull, no reason to preserve the config + this.getAEItemHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + @Override + public void onDistinctChange(boolean newValue) { + super.onDistinctChange(newValue); + if (!getWorld().isRemote && !newValue) { + // Ensure that our configured items won't match any other buses in the multiblock. + // Needed since we allow duplicates in distinct mode on, but not off + validateConfig(); + } + } + + /** + * Test for if any of our configured items are in another stocking bus on the multi + * we are attached to. Prevents dupes in certain situations. + */ + private void validateConfig() { + for (var slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() != null) { + ItemStack configuredStack = slot.getConfig().createItemStack(); + if (testConfiguredInOtherBus(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + /** + * @return True if the passed stack is found as a configuration in any other stocking buses on the multiblock. + */ + private boolean testConfiguredInOtherBus(ItemStack stack) { + if (stack == null || stack.isEmpty()) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + // In distinct mode, we don't need to check other buses since only one bus can run a recipe at a time. + if (!(controller instanceof RecipeMapMultiblockController rmmc) || !rmmc.isDistinct()) { + // Otherwise, we need to test for if the item is configured + // in any stocking bus in the multi (besides ourselves). + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_ITEMS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingItemList aeList) { + // We don't need to check for ourselves, as this case is handled elsewhere. + if (aeList == this.aeItemHandler) continue; + if (aeList.hasStackInConfig(stack, false)) { + return true; + } + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEItemHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + /** + * Refresh the configuration list in auto-pull mode. + * Sets the config to the first 16 valid items found in the network. + */ + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEItemStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + ItemStack itemStack = stack.createItemStack(); + if (itemStack == null || itemStack.isEmpty()) continue; + // Ensure that it is valid to configure with this stack + if (autoPullTest != null && !autoPullTest.test(itemStack)) continue; + IAEItemStack selectedStack = WrappedItemStack.fromItemStack(itemStack); + if (selectedStack == null) continue; + IAEItemStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEItemHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEItemHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + private static class ExportOnlyAEStockingItemSlot extends ExportOnlyAEItemSlot { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemSlot(IAEItemStack config, IAEItemStack stock, + MetaTileEntityMEStockingBus holder) { + super(config, stock); + this.holder = holder; + } + + public ExportOnlyAEStockingItemSlot(MetaTileEntityMEStockingBus holder) { + super(); + this.holder = holder; + } + + @Override + public ExportOnlyAEStockingItemSlot copy() { + return new ExportOnlyAEStockingItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + this.holder); + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + if (this.config != null) { + // Extract the items from the real net to either validate (simulate) + // or extract (modulate) when this is called + IMEMonitor monitor = holder.getMonitor(); + if (monitor == null) return ItemStack.EMPTY; + + Actionable action = simulate ? Actionable.SIMULATE : Actionable.MODULATE; + IAEItemStack request; + if (this.config instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(amount); + + IAEItemStack result = monitor.extractItems(request, action, holder.getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), amount); + this.stock.decStackSize(extracted); // may as well update the display here + if (this.trigger != null) { + this.trigger.accept(0); + } + if (extracted != 0) { + ItemStack resultStack = this.config.createItemStack(); + resultStack.setCount(extracted); + return resultStack; + } + } + } + } + return ItemStack.EMPTY; + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip.2")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemList(MetaTileEntityMEStockingBus holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder) { + if (!(holder instanceof MetaTileEntityMEStockingBus stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Item List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingItemSlot(stocking); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + @Override + public ExportOnlyAEStockingItemSlot[] getInventory() { + return (ExportOnlyAEStockingItemSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + boolean inThisBus = super.hasStackInConfig(stack, false); + if (inThisBus) return true; + if (checkExternal) { + return holder.testConfiguredInOtherBus(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java new file mode 100644 index 00000000000..1693ece229b --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -0,0 +1,375 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingHatch extends MetaTileEntityMEInputHatch { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingHatch(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingHatch(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingFluidList getAEFluidHandler() { + if (this.aeFluidHandler == null) { + this.aeFluidHandler = new ExportOnlyAEStockingFluidList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingFluidList) this.aeFluidHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + } + + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingFluidSlot slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEFluidStack request; + if (slot.getConfig() instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEFluidStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + this.autoPullTest = stack -> !this.testConfiguredInOtherHatch(stack); + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + this.autoPullTest = $ -> false; + if (this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + private void validateConfig() { + for (var slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() != null) { + FluidStack configuredStack = slot.getConfig().getFluidStack(); + if (testConfiguredInOtherHatch(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + private boolean testConfiguredInOtherHatch(FluidStack stack) { + if (stack == null) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_FLUIDS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingFluidSlot aeSlot) { + if (aeSlot.getConfig() == null) continue; + if (getAEFluidHandler().ownsSlot(aeSlot)) continue; + if (aeSlot.getConfig().getFluid().equals(stack.getFluid())) { + return true; + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEFluidStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + FluidStack fluidStack = stack.getFluidStack(); + if (fluidStack == null) continue; + if (autoPullTest != null && !autoPullTest.test(fluidStack)) continue; + IAEFluidStack selectedStack = WrappedFluidStack.fromFluidStack(fluidStack); + IAEFluidStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEFluidHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEFluidHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip.2")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, + IAEFluidStack stock, MetaTileEntity entityToNotify) { + super(holder, config, stock, entityToNotify); + } + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, MetaTileEntity entityToNotify) { + super(holder, entityToNotify); + } + + @Override + protected MetaTileEntityMEStockingHatch getHolder() { + return (MetaTileEntityMEStockingHatch) super.getHolder(); + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEStockingFluidSlot( + this.getHolder(), + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + @Override + public @Nullable FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + if (this.config != null) { + IMEMonitor monitor = getHolder().getMonitor(); + if (monitor == null) return null; + + Actionable action = doDrain ? Actionable.MODULATE : Actionable.SIMULATE; + IAEFluidStack request; + if (this.config instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(maxDrain); + + IAEFluidStack result = monitor.extractItems(request, action, getHolder().getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), maxDrain); + this.stock.decStackSize(extracted); + trigger(); + if (extracted != 0) { + FluidStack resultStack = this.config.getFluidStack(); + resultStack.amount = extracted; + return resultStack; + } + } + } + return null; + } + } + + private static class ExportOnlyAEStockingFluidList extends ExportOnlyAEFluidList { + + private final MetaTileEntityMEStockingHatch holder; + + public ExportOnlyAEStockingFluidList(MetaTileEntityMEStockingHatch holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + if (!(holder instanceof MetaTileEntityMEStockingHatch stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Fluid List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingFluidSlot(stocking, entityToNotify); + } + } + + @Override + public ExportOnlyAEStockingFluidSlot[] getInventory() { + return (ExportOnlyAEStockingFluidSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + boolean inThisHatch = super.hasStackInConfig(stack, false); + if (inThisHatch) return true; + if (checkExternal) { + return holder.testConfiguredInOtherHatch(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java new file mode 100644 index 00000000000..fd4b40ea7e5 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java @@ -0,0 +1,64 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.storage.data.IAEFluidStack; + +public class ExportOnlyAEFluidList { + + protected final int size; + protected ExportOnlyAEFluidSlot[] inventory; + + public ExportOnlyAEFluidList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + this.size = slots; + createInventory(holder, entityToNotify); + } + + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this.inventory = new ExportOnlyAEFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEFluidSlot(holder, entityToNotify); + } + } + + public ExportOnlyAEFluidSlot[] getInventory() { + return inventory; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + if (stack == null) return false; + for (ExportOnlyAEFluidSlot slot : inventory) { + IAEFluidStack config = slot.getConfig(); + if (config != null && config.getFluid().equals(stack.getFluid())) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } + + public boolean ownsSlot(ExportOnlyAEFluidSlot testSlot) { + for (var slot : inventory) { + if (slot == testSlot) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java new file mode 100644 index 00000000000..73ad45f9ac4 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java @@ -0,0 +1,192 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import appeng.api.storage.data.IAEFluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class ExportOnlyAEFluidSlot extends ExportOnlyAESlot + implements IFluidTank, INotifiableHandler, IFluidHandler { + + private final List notifiableEntities = new ArrayList<>(); + private MetaTileEntity holder; + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { + super(config, stock); + this.holder = holder; + this.notifiableEntities.add(mte); + } + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this(holder, null, null, entityToNotify); + } + + public ExportOnlyAEFluidSlot() { + super(); + } + + @Override + public IAEFluidStack requestStack() { + IAEFluidStack result = super.requestStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEFluidStack exceedStack() { + IAEFluidStack result = super.exceedStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEFluidStack stack) { + if (this.stock == null) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else { + this.stock.add(stack); + } + trigger(); + } + + @Override + public void setStack(IAEFluidStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else if (this.stock == null || this.stock.getFluid() != stack.getFluid()) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else if (this.stock.getStackSize() != stack.getStackSize()) { + this.stock.setStackSize(stack.getStackSize()); + } else return; + trigger(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Nullable + @Override + public FluidStack getFluid() { + if (this.stock != null && this.stock instanceof WrappedFluidStack) { + return ((WrappedFluidStack) this.stock).getDelegate(); + } + return null; + } + + @Override + public int getFluidAmount() { + return this.stock != null ? (int) this.stock.getStackSize() : 0; + } + + @Override + public int getCapacity() { + // Its capacity is always 0. + return 0; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return new IFluidTankProperties[] { + new FluidTankProperties(this.getFluid(), 0) + }; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return 0; + } + + @Nullable + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { + return this.drain(resource.amount, doDrain); + } + return null; + } + + @Nullable + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); + FluidStack result = new FluidStack(this.stock.getFluid(), drained); + if (doDrain) { + this.stock.decStackSize(drained); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + trigger(); + } + return result; + } + + @Override + public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.add(metaTileEntity); + } + + @Override + public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.remove(metaTileEntity); + } + + protected void trigger() { + for (MetaTileEntity metaTileEntity : this.notifiableEntities) { + if (metaTileEntity != null && metaTileEntity.isValid()) { + this.addToNotifiedList(metaTileEntity, this, false); + } + } + if (holder != null) { + holder.markDirty(); + } + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEFluidSlot( + this.holder, + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + protected MetaTileEntity getHolder() { + return holder; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java new file mode 100644 index 00000000000..995670eff15 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java @@ -0,0 +1,126 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +public class ExportOnlyAEItemList extends NotifiableItemStackHandler { + + protected final int size; + protected ExportOnlyAEItemSlot[] inventory; + + public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify, false); + this.size = slots; + createInventory(holder); + } + + protected void createInventory(MetaTileEntity holder) { + this.inventory = new ExportOnlyAEItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEItemSlot(); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + public ExportOnlyAEItemSlot[] getInventory() { + return inventory; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + for (int index = 0; index < size; index++) { + if (nbt.hasKey("#" + index)) { + NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); + this.inventory[index].deserializeNBT(slotTag); + } + } + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + for (int index = 0; index < size; index++) { + NBTTagCompound slot = this.inventory[index].serializeNBT(); + nbt.setTag("#" + index, slot); + } + return nbt; + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + // NO-OP + } + + @Override + public int getSlots() { + return size; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].getStackInSlot(0); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].extractItem(0, amount, simulate); + } + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } + + @Override + protected int getStackLimit(int slot, @NotNull ItemStack stack) { + return Integer.MAX_VALUE; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + if (stack == null || stack.isEmpty()) return false; + for (ExportOnlyAEItemSlot slot : inventory) { + IAEItemStack config = slot.getConfig(); + if (config != null && config.isSameType(stack)) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java new file mode 100644 index 00000000000..1408d77ad49 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java @@ -0,0 +1,138 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.items.IItemHandlerModifiable; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class ExportOnlyAEItemSlot extends ExportOnlyAESlot implements IItemHandlerModifiable { + + protected Consumer trigger; + + public ExportOnlyAEItemSlot(IAEItemStack config, IAEItemStack stock) { + super(config, stock); + } + + public ExportOnlyAEItemSlot() { + super(); + } + + public void setTrigger(Consumer trigger) { + this.trigger = trigger; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Override + public ExportOnlyAEItemSlot copy() { + return new ExportOnlyAEItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy()); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) {} + + @Override + public int getSlots() { + return 1; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot == 0 && this.stock != null) { + return this.stock.getDefinition(); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + int extracted = (int) Math.min(this.stock.getStackSize(), amount); + ItemStack result = this.stock.createItemStack(); + result.setCount(extracted); + if (!simulate) { + this.stock.decStackSize(extracted); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + } + if (this.trigger != null) { + this.trigger.accept(0); + } + return result; + } + return ItemStack.EMPTY; + } + + @Override + public IAEItemStack requestStack() { + IAEItemStack result = super.requestStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEItemStack exceedStack() { + IAEItemStack result = super.exceedStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEItemStack stack) { + if (this.stock == null) { + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } else { + this.stock.add(stack); + } + this.trigger.accept(0); + } + + @Override + public void setStack(IAEItemStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else { + // todo this could maybe be improved with better comparison check + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } + this.trigger.accept(0); + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java similarity index 94% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java index 8d5027add51..316a76e422b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java @@ -1,4 +1,4 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.INBTSerializable; @@ -6,11 +6,6 @@ import appeng.api.storage.data.IAEStack; import org.jetbrains.annotations.Nullable; -/** - * @author GlodBlock - * @Description A export only slot to hold {@link IAEStack} - * @date 2023/4/22-13:42 - */ public abstract class ExportOnlyAESlot> implements IConfigurableSlot, INBTSerializable { @@ -64,7 +59,9 @@ public T exceedStack() { return null; } - abstract void addStack(T stack); + public abstract void addStack(T stack); + + public abstract void setStack(T stack); @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java similarity index 66% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java index 6cc3a48771d..9e4532c8f19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java @@ -1,10 +1,5 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; -/** - * @Author GlodBlock - * @Description A slot that can be set to keep requesting. - * @Date 2023/4/21-0:34 - */ public interface IConfigurableSlot { T getConfig(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java index 854996b0db4..274d4aac26c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java @@ -191,12 +191,18 @@ public boolean sameOre(IAEItemStack iaeItemStack) { @Override public boolean isSameType(IAEItemStack iaeItemStack) { - return false; + if (iaeItemStack == null) return false; + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(iaeItemStack); } @Override public boolean isSameType(ItemStack itemStack) { - return false; + if (this.delegate.isEmpty()) return itemStack.isEmpty(); + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(itemStack); } @Override diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index 013e759001f..39e12fe8af3 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -8,6 +8,7 @@ import gregtech.api.recipes.ingredients.GTRecipeItemInput; import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; import net.minecraft.init.Blocks; @@ -1024,6 +1025,24 @@ public static void init() { .inputs(accelerationCard.copy()) .output(ITEM_IMPORT_BUS_ME) .duration(300).EUt(VA[HV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(ITEM_IMPORT_BUS[IV]) + .inputs(normalInterface.copy()) + .input(CONVEYOR_MODULE_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_BUS_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(FLUID_IMPORT_HATCH[IV]) + .inputs(fluidInterface.copy()) + .input(ELECTRIC_PUMP_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_HATCH_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 5e2feb89be3..80821f7237b 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5259,15 +5259,27 @@ gregtech.machine.laser_hatch.tooltip2=§cLaser Cables must be in a straight line gregtech.machine.fluid_tank.max_multiblock=Max Multiblock Size: %,dx%,dx%,d gregtech.machine.fluid_tank.fluid=Contains %s L of %s -gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +# ME Parts +gregtech.machine.me_import_item_bus.name=ME Input Bus +gregtech.machine.me.item_import.tooltip=Extracts specified items from the ME network +gregtech.machine.me_stocking_item_bus.name=ME Stocking Input Bus +gregtech.machine.me.stocking_item.tooltip=Retrieves items directly from the ME network +gregtech.machine.me.stocking_item.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 items in the ME system, updated every 5 seconds. +gregtech.machine.me_import_item_hatch.configs.tooltip=Keeps 16 item types in stock +gregtech.machine.me_import_fluid_hatch.name=ME Input Hatch +gregtech.machine.me.fluid_import.tooltip=Extracts specified fluids from ME network +gregtech.machine.me_stocking_fluid_hatch.name=ME Stocking Input Hatch +gregtech.machine.me.stocking_fluid.tooltip=Retrieves fluids directly from the ME network +gregtech.machine.me.stocking_fluid.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 fluids in the ME system, updated every 5 seconds. +gregtech.machine.me_import_fluid_hatch.configs.tooltip=Keeps 16 fluid types in stock gregtech.machine.me_export_item_bus.name=ME Output Bus -gregtech.machine.me_import_fluid_hatch.name=ME Stocking Input Hatch -gregtech.machine.me_import_item_bus.name=ME Stocking Input Bus -gregtech.machine.me.fluid_export.tooltip=Stores fluid directly into ME network. -gregtech.machine.me.item_export.tooltip=Stores item directly into ME network. -gregtech.machine.me.fluid_import.tooltip=Fetch fluids from ME network automatically. -gregtech.machine.me.item_import.tooltip=Fetch items from ME network automatically. -gregtech.machine.me.export.tooltip=It has infinite capacity before connecting to ME network. +gregtech.machine.me.item_export.tooltip=Stores items directly into the ME network +gregtech.machine.me.item_export.tooltip.2=Can cache an infinite amount of items +gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +gregtech.machine.me.fluid_export.tooltip=Stores fluids directly into the ME network +gregtech.machine.me.fluid_export.tooltip.2=Can cache an infinite amount of fluid +gregtech.machine.me.stocking_auto_pull_enabled=Auto-Pull Enabled +gregtech.machine.me.stocking_auto_pull_disabled=Auto-Pull Disabled # Universal tooltips gregtech.universal.tooltip.voltage_in=§aVoltage IN: §f%,d EU/t (%s§f) @@ -5405,8 +5417,12 @@ gregtech.gui.me_network.offline=Network Status: §4Offline§r gregtech.gui.waiting_list=Sending Queue: gregtech.gui.config_slot=§fConfig Slot§r gregtech.gui.config_slot.set=§7Click to §bset/select§7 config slot.§r +gregtech.gui.config_slot.set_only=§7Click to §bset§7 config slot.§r gregtech.gui.config_slot.scroll=§7Scroll wheel to §achange§7 config amount.§r gregtech.gui.config_slot.remove=§7Right click to §4clear§7 config slot.§r +gregtech.gui.config_slot.auto_pull_managed=§4Disabled:§7 Managed by Auto-Pull +gregtech.gui.me_bus.extra_slot=Extra Slot/n§7Put extra items for recipes here, like Molds or Lenses +gregtech.gui.me_bus.auto_pull_button=Click to toggle automatic item pulling from ME gregtech.gui.alarm.radius=Radius: diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png index 76486f57cddf495f9f58ce74646a9ccc9c56afac..dd3d1f12037c5f85d9801b81d745aaba4be77205 100644 GIT binary patch delta 182 zcmbQmc${&9WIZzj1A~Sxe=v|@EDmyaVpw-h<|UBBlJ4m1$iT3%pZiZDE0E70;1lBN z;NY-g#fp@al=qcFKrvINS%G|>0G|+72M34ul|m^gDL{b*R@%2f>PmwAg8%>j&)}f7@(Ym9S>O>_%)r36 z41^im@2t!R3L1L4IEH8hCnvZu-(ZoLz@W$Irs2S0(8yTF=q7MXyI~=#F9X*DCXR+! g2GIqa2FA<`&n7T#e60KB6HqgQr>mdKI;Vst00y5j5C8xG literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png index f19def26e3015ebd2d36784d2b2bde5fee921cfa..a2644c44b468a44e4f7e1ca4a5dcd2d60a61fbd7 100644 GIT binary patch delta 182 zcmbQmc${&9WIZzj1A~Sxe=v|@EDmyaVpw-h<|UBBlJ4m1$iT3%pZiZDE0E70;1lBN z;NY-g#fp@a6kf+gK(R-gdM*Je){-E<;Qv6t@Ov8{$RN%FkH}&M2EM}}%y>M1MG8>R zz|+MsL?bvk!IAj}i^K#5Jw`VT2M&FMM#ehEv@|CsiKq)K3mEho7;dlzFwSD&=4Mcf WXVOgk77sLufx*+&&t;ucLK6TwcQV}o delta 137 zcmX@kIE!(DWIY=L1B3kM|A{~<(bL5-#G*G@qTm2W@qsQ;?SGRW&FJXh*bpa{a_~zj zcgH0gV-3c0X^TuaA~tXqRo+ev{geAzk;kwrw&6NMUaYBs+HHm;hHC~5jq9i93z{^U p=^YTe^`(%ph)Y_jp|O#XA=p>Y;#2yGSfFJLp00i_>ztSpngHZNS%G|>0G|+72L}gU$3-bADL{ck%Ukb*)RhGJ1^@s5pTR+EF)x7&9|Go4~m7vF?{oK+O!Eu6{1-oD!M|L rG=erRz!uu{aRG7)8zO*#fdK%QvJtvQCq}~n0000NS%G|>0G|-o_mx5p4h|_PDL{ch?|Z92>PmwAg8%>j&)}f7@(Ym9S>O>_%)r36 z41^im@2t!R3L1F2IEH8hCnvZu-(ZoLz~Is#$XCE^(8yTF$j0WxBoTFiC4pf&gAfDv f0wxp2v^0kA6BsWl@3ayJ>SgeB^>bP0l+XkK$uBR{ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png index 313e4fdbeb65f380306ed3f8419c5833ecfb1f13..e13a7f0fb7c07ebb8cfc5a6491eb8989871c2c4c 100644 GIT binary patch delta 182 zcmbQmc${&9WIZzj1A~Sxe=v|@EDmyaVpw-h<|UBBlJ4m1$iT3%pZiZDE0E70;1lAy zV#Nvv2ZxlD6kf+gKry+kcb5Vw){-E<;Qv6t@Ov8{$RN%FkH}&M2EM}}%y>M1MG8>R zz|+MsL?bvk!IAj}i^K#5mj*$;0&abSM#ehEv@|CsiKq)K2@KO2gc!INFqtrli7{B# WGx=_re=Y&2nZeW5&t;ucLK6V{)G|{5 delta 137 zcmV;40CxY!0h$4j8Gi-<001BJ|6u?C0AWc)K~y-6V;FG22y?)S6)XOe;+Tkt2(Vrj zWWltG=|pLs)sYEjGf^4@EZ77&gjBIA{_*ZMh8V>zz-s`Xq9YiSZ2&ONS%G|>0G|+7UdKfa4h|_PDL{djyOQ>T)RhGJ1^@s5pTR+E%w=boFyt=akR{0PuevF#rGn literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png b/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png new file mode 100644 index 0000000000000000000000000000000000000000..5613c4a37856c9ea6bddc0ad15a7d8852e8734d8 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!V2-DYV~B-+vIJ{EKuE|J`BN^8J^`~-CQO*n zkSL)%g^f98n__eM`+JU&JUrZDIt{Pg3k5v{6?vHTDllUs+WpRATAquubtu zi!_ITX!eaHPFaB-(;; zJ)TjhjZtxT&VSn(K#iOQ9+AZi419+{nDKc2iWHz=uBVG*h{pNk1|~N)H%9}3L#GAI z49$30j4$2hS>7c1_Vk`|b|y)sNYQHvZ3WemA*XIgE}FqHxpj&{1EZI=k%rR}mJdb_ z?<_ge815FcpUH@S_Whm01jdqn*%^#Q{4QKC<~6hMv>37+Sa|3F1B3oGmCT044tYR} O89ZJ6T-G@yGywpki&`)M literal 0 HcmV?d00001 From 35b2ffbc524c0be56d518de417c906d7b8c49922 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:15:00 -0600 Subject: [PATCH 092/168] Electric Wirecutter (#2404) (cherry picked from commit 4e47ef8e75cab83ffa25dc90b80adf37add2cafd) --- .../java/gregtech/common/items/ToolItems.java | 33 ++++++++++++++++++ .../recipe/handlers/ToolRecipeHandler.java | 19 ++++++++++ .../resources/assets/gregtech/lang/en_us.lang | 3 ++ .../dull/tool_head_wirecutter.json | 6 ++++ .../models/item/tools/wire_cutter_hv.json | 7 ++++ .../models/item/tools/wire_cutter_iv.json | 7 ++++ .../models/item/tools/wire_cutter_lv.json | 7 ++++ .../tools/handle_electric_wire_cutter_hv.png | Bin 0 -> 2552 bytes .../tools/handle_electric_wire_cutter_iv.png | Bin 0 -> 2532 bytes .../tools/handle_electric_wire_cutter_lv.png | Bin 0 -> 2508 bytes .../items/tools/wire_cutter_electric.png | Bin 0 -> 1786 bytes 11 files changed, 82 insertions(+) create mode 100644 src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json create mode 100644 src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json create mode 100644 src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json create mode 100644 src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png create mode 100644 src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png diff --git a/src/main/java/gregtech/common/items/ToolItems.java b/src/main/java/gregtech/common/items/ToolItems.java index 05e2453846b..5545387ef7c 100644 --- a/src/main/java/gregtech/common/items/ToolItems.java +++ b/src/main/java/gregtech/common/items/ToolItems.java @@ -55,6 +55,9 @@ public final class ToolItems { public static IGTTool BUZZSAW; public static IGTTool SCREWDRIVER_LV; public static IGTTool PLUNGER; + public static IGTTool WIRECUTTER_LV; + public static IGTTool WIRECUTTER_HV; + public static IGTTool WIRECUTTER_IV; private ToolItems() {/**/} @@ -319,6 +322,36 @@ public static void init() { .oreDict(ToolOreDict.toolPlunger) .toolClasses(ToolClasses.PLUNGER) .markerItem(() -> ToolHelper.getAndSetToolData(PLUNGER, Materials.Rubber, 255, 1, 4F, 0F))); + WIRECUTTER_LV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_lv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(2.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.LV)); + WIRECUTTER_HV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_hv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(3.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.HV)); + WIRECUTTER_IV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_iv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(4.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.IV)); } public static IGTTool register(@NotNull ToolBuilder builder) { diff --git a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java index 4b6ec9210b2..1997631a38c 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java @@ -287,6 +287,10 @@ private static void processElectricTool(OrePrefix prefix, Material material, Too .EUt(8 * voltageMultiplier) .buildAndRegister(); } + + // wirecutter + addElectricWirecutterRecipe(material, + new IGTTool[] { ToolItems.WIRECUTTER_LV, ToolItems.WIRECUTTER_HV, ToolItems.WIRECUTTER_IV }); } // screwdriver @@ -316,6 +320,21 @@ public static void addElectricToolRecipe(OrePrefix toolHead, Material material, } } + public static void addElectricWirecutterRecipe(Material material, IGTTool[] toolItems) { + for (IGTTool toolItem : toolItems) { + int tier = toolItem.getElectricTier(); + ItemStack powerUnitStack = powerUnitItems.get(tier).getStackForm(); + IElectricItem powerUnit = powerUnitStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); + ItemStack tool = toolItem.get(material, 0, powerUnit.getMaxCharge()); + ModHandler.addShapedEnergyTransferRecipe(String.format("%s_%s", toolItem.getToolId(), material), tool, + Ingredient.fromStacks(powerUnitStack), true, true, + "PfP", "hPd", "RUR", + 'P', new UnificationEntry(OrePrefix.plate, material), + 'U', powerUnitStack, + 'R', new UnificationEntry(OrePrefix.stick, material)); + } + } + public static void addToolRecipe(@NotNull Material material, @NotNull IGTTool tool, boolean mirrored, Object... recipe) { if (mirrored) { diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 80821f7237b..3cd60ebeed0 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1008,6 +1008,9 @@ item.gt.tool.screwdriver_lv.name=%s Screwdriver (LV) item.gt.tool.screwdriver_lv.tooltip=§8Adjusts Covers and Machines item.gt.tool.plunger.name=%s Plunger item.gt.tool.plunger.tooltip=§8Removes Fluids from Machines +item.gt.tool.wire_cutter_lv.name=%s Wire Cutter (LV) +item.gt.tool.wire_cutter_hv.name=%s Wire Cutter (HV) +item.gt.tool.wire_cutter_iv.name=%s Wire Cutter (IV) item.gt.tool.tooltip.crafting_uses=§a%s Crafting Uses diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json new file mode 100644 index 00000000000..92690c87e45 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/tool_head_wire_cutter" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json new file mode 100644 index 00000000000..60a5a9255c1 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_hv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json new file mode 100644 index 00000000000..6a7f378d8a9 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_iv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json new file mode 100644 index 00000000000..406df61785c --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_lv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png new file mode 100644 index 0000000000000000000000000000000000000000..b54d8d136c2f0e8692327d3b940f495d641295d2 GIT binary patch literal 2552 zcmcIm+i%-c7No;Jl zNj9`;z3kq#qXTv+($GMvP?Em;lr~tGYhk)FD@)xzHs5asp+$hGkNgf@yW^g<0sxc zGq*T5w>UksU|EL`9XdTd{raiX=QnQLxOMB+GqV?q#iQBm!CdY&+ny|yj$vQcuV24u z)28h^b{v_UpO}~#+h1yEXlU8c($&?K$rOA(Ut3!n*-bVzHFb1!VEiR85W|nKn;05d z`4<<_%q+i*iJGl}7afAw^0aq1T?Bgo+Ag$RSrH zi@9vxQHo)zOswGV-Zn##Wr#Z#rXt>n@#gdN`8)p002^w{bC@1G$`&OIlyrY z5E&rTKvFnP;bgLUQTRNP4B2{0NyMJ5o`+XqD&xAA!Z3wG!C&D0rk!S3S(X{VF&sx@ z1nrdau3Dt?&bA6kl_rK9Xd9Mmn0eBpRW)ZRE*0DHU@pv7+CT%WPM>}r+1oo&J;F@SBS+Wq5K#n%*vRq>151%#8Lmb9*w2+*+_LwJ87EPTE&KIEF{PK1+r(Kk=MIFdsfC@B@1);01`Zq9}WPu{$QVV|po4S!IJrJrx zC1u(<6=%uFscFPm`E>cTcw8CGJFc3CXfPJ0u&aK<(3OCuLz$I%I=~{97Jwkpnk);n zrU{w`cuftYf;Ib?3CFz(*6ej`52aK<)exiw83pN-B#5-e2UMDs051SthkQz{*}q^L zxR=!Iqw~}&r1Y6t(~g@u&N5#UF_v*zPRfAc;F^`n4N~cra+{2xS66LSMV~duvZ@pn zdcqG=(5pDosp__|M$#TG=n8EigD~lRlu&^=X38z7Hj1Qif*-6j<{<)c)QS6t!RY}p zrSUQiMNXm-CjdGqvmBj*f(SG%$V$9eOT*n^@CqAH0AJJSBZW~hf*CcRM)=)|`}{u% z?BPVcW_|8%zW*Vx5aYdGSIaTPtgYP89mUtWCW1TIlee=<0%dte)%2>Zy1aK+29Rz- z+^%=%f;5ZA7Q{U-3LK65UZf%9Asdi@AnU1$pIPG{(8@d~c@(q;bU?GLpwY4< zrD$1&K;%&{D6!HSw3V&Z5rmjKzTPYJiq)#IRd%$pi)SKU;k?!+vbU;Fb(F_)v+>N{ za_fgPc-~J8#v;j{5%^)GadR^O(H_w3+k11@GTF7``i)y(eD!6ke%)6re){`w>wIUg zH8r0)e)7cgWal$Gx6|9cKGHV7u&*tVOdM@mTKazJm-ojq`;ESv-+X)fJDkVI1|zLv ufW0j>I_k&gUmE>ss?!?#V7dF+Y%B5WlR{(ryZ)T_mt(MhD0Vga%H*FW_%)RP literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png new file mode 100644 index 0000000000000000000000000000000000000000..303fea217f6ee5fa49bdbbc901d221d81931c863 GIT binary patch literal 2532 zcmcImTWs4@7LU+qY?_2LAx%6m9ySTIO@py_UO@1~D@aJ?IJXtnU6{a<8%s#VRI;+c zFzKw1R9hK0HGv?dl+>3eCY)z8Cv>?eA3Ub=7-`2RCS6@ANh7aokmz#hkiNWY*RFm0 z_N7o+1*SOsnlyThp1)(qj=sLW1H;4exFH^RrK6*xduR9H;GnSo{jB2<(ed3t9TU6Fv-c9XW(TLvL-3oPKx{O%da@rwo=>?B?oif6e-!WCw;PXaz2kw zE@R!|CMSBjlQl#cDkL=6TBYm+sFvdD#E5>6wt0@NL&D`0myS+kkLDKGDc2{g78e1A z5VD#cS5%dlSQ%$UD2hB(c&G!YAyGu4&NeTOp2xCD-zuQR>~qcY=qkmP!q7uJU#(W- zRVnWJMPAT#orfYXihv?Ou;zqD4LHI621%19O9JfMUTC`x8_^o3yAq~2>T)BNir40L zf@Z>K>iC-B@j@I%vDJYVZsWWazg+jg!aOOH3UR`KVud!ArYo0g!?&cZRNCkuoL;3K zH3Qrd9pu+M!Y`7*UGXuQUZp4QZ#m|b+|Uh5?mgmY|J;toLsLF6Lf6l`Zn;&lg%%4d zN^zMTIbu7OTMb5|QyQS~^8Qk~Rht2*L(5M+IRSq45u}kQX3Q zXsPADfnCcktUVBFVN`Jaib1nvSBxUzJ*QYdEtf-cP7oRnCUe;oM_rBEwuMyF!n&YK zKoy7pWGHLE)O8t{rfix}G7YtmXxV37yb@KgWp7b?tQAzlBpAp#Nq~YTE5MXg0|*+F zWN2AfDi|&M7k!)dl2Lwio_2-Mlv{TFoNLi6ODz#o8Q0~6X6=C1Y^~lPjc%#8$r3rS zX{#yvvdz|2g$x`CKgHpw;>6;b+x8Yod$^z*wAB)!r1w!m0~WZ2uxj`uU8D(qu+sR4 z2qZ98?;nO}sY=0=bbu9614NV|Na%tH3RqU4X(j|sQd()aI}8a4DuPl=qmL9u!w8oQ zr%33#mG=3664=9uddvFU-F*K;U`alDy>6CclHXdn$vcW~bxoRfa3t?wlLYGW&KSi_ zTWxtyGzO66V%n~E=n@i6=%kxJAEusJ> zv>*@!*#x?#6@YGFs7NG{&;)G@+Q!!A2$K9AU+)!q!)nvmsyo`)r8AMPXkJ?rIa;-+ zI&rAnd^)rD-uUG`I`3EKvg!QD5{5I|_H;p*8G&7~!`H^ovxCEzuip6jn=3um5t#H$3D2&+4b(*@0@;t9XL38W$gMhr+R<<=;OW*k1V{^IWoF_ZuZP)XV0F?T)TPm zhwp#B{oVGtbkFTu+D$bU7+*X&uwFVf;4SB_vllPv%%?x`=ij(>97KOP=BDSf7c$4* F{0pFb6#oDK literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png new file mode 100644 index 0000000000000000000000000000000000000000..c45bffa43605a2c3858313c423a5ef2d17126870 GIT binary patch literal 2508 zcmcImYitx%7~O)c6=*C3OQSRlLs3*_=e@Ht?1H7+(i#^^S)r&uI&nLs*zLnyE>}@)O`sm#i=C^m0DX_^>zC0j&#Ip>-PN^s>`!QLQ@A2n z;c{($cKDxiJ{sQ=ubFSTTqWhsmACe`&qljkH}~tI2D>5nfCP-FTUHGPx|7j3Lc3hP zY00<@7C;+QU|5g&@pIifa7=>lNv~-);hgrFA<(`6h$=p9YSA!XQbG(- zXvGAy|i18YaX9H$wo5qA)>p^BxaW06!UH zD25>^o}@&A5+sI^7!k{SaI_zW`Ak)l>I2o8{m{sdH`#VvBFRJ|;ZCq_!wi$OD2gP- zkPJg01YxzsY&l89tO;q73{3!9z|`ZmZp1K$R#uD_+mEA=(^{hO9CyshBn+jFOv-VR zc2kbF6i@{@T)f4Mq#{rO2_rBHW448`bPkKs6%6L!gVIK$IkaV0wW5eJ0tZD~p|&_A z>!D?|m;hF_q8%q>1B*8qwqZ3HSJ09BJEtZtRhm$?4KrjIk!;24vMd%8|D%qXPG+cB{_2AJh=)NW&~cvlFrjE5azj*LE6t9YQR* z_3APh)x&EFD-wWb1OhS~MR-M;AvD18l%jZPf#tJlxLgJ+(H@CnvmU)68R7c)(Q7 z-c!>DkZJ(bu9xV%Ebxj@^AMEcMLo}R41xNdCjejp?GY$WRJC-R5&d7#iYy~I6of*l z6hYIRLWqK(5uywzo`qhoKnsJ=rl$rf@R65dy^{3wssYDVD$w*SIup?dg+5WFK?-;hsWbjckWK?8_`od^5Up5r}}!%-|Bkt z)GIxw_a}WD4mG!QEv`O0YWELJA4~7>s?l^YBmO5Lz-(Ga=x4yDf_fP!AH)dCF zvGw?h>hQb9(N%lSA%&uA^gJ;YRPy zgS*!6{Q1K6_ga2^*< z6g18+X_3mdmyLKeAeUkzhI~79WqI$yZ}Ns7;CQpQd+7I1eN_I(!=-rP^!$dy&-do9 z(Kdb2+_`7u@3USwaejGad)?a87uMwEovohGcd)Q?+?#ci>Rzi~x+rQb?pXa*^%?Cc m*Sn#~B^`vd=4gL$Z`u1(zMk^vR$FpjscNfc2D+vK+Ik`9XCMQdB zdv80%54usc17+wa^T+nXiThE}NkLlZ27bWorda&7Kb@1QjIn_~rW7_$?nltsZexLy zoa8+3^L{*U-nR$(ds~_xYo;iwCEb@AB+pI$+VCK`Kl$fPNFEQ_eY;(XdgLj8HKYf( zUZbc7=8epVH=^v6RcwZ!hO;PCHf@5YsLrmk4b@TP(OHx;tORp)evzRKEx`;&6`G9fUL2kEj|uw1#EU@E*a+54Y4hOR)o(FD`&JETXH z0Xm5tM8`t{s{#P%xD<-UVkoOdJ7@t20tccTkXR6x1wj@hx^^+douldUU}{Ir8F@=E zdC#+Djw_W)p;9=6ogBwYlEeXl69kqZSa;m=V41btEp>(za#hE$Jp)^`&j_=)=p`5u zYBdMb4rnd6Rwq(1t_*FC4*@@?3Q$u6oLzJZ73Z4Dp#n0I<+%jQ2Ut=jMG4?*(wb&~ zcDYL;HPLQn+(z6Wa&gg7QO_9hxTPMLoyQ(_^LU*+g5w|?TTVI%df3TeT&OEG zP-mfqa414QJ#1JSF1c;Kmzn`eK@TMuqFRIn0?UI8ku1u~Ahr#NG5}SmLK;DX9{fKz zEb}p$m;M9BnxT*15vr-OjvW({Dj6osAo|nr!CimmWtA;1Vcg%8HOh7FdUAl zVUdkUS%Ho4kvJ<#YK+zOm-H}?2Kj|x;of-yh2$hIU`N3ksdCuw-%20JeTGZK8n68kLuhYpS1{;G z>&Q^`yF0~PG@7PY3e;dqG@)AsBWD#nI z%-izUyAP3B{e3#soe>XSd7rl?w?EvoIQ&&(-_f1DFZ7<}#rv98I$oNbpFV!<=>7v% z=iI{C9cT2WwogwkoRzZ zN;}-Ja&h119q(RQ?WayHWp;hAf7A5LAI;Z(J+<^> Date: Wed, 6 Mar 2024 21:33:51 -0600 Subject: [PATCH 093/168] Allow PSS to display on CM (#2405) (cherry picked from commit fd65290173b5de45c22ad1e0398bfd3714b70689) --- .../common/covers/CoverDigitalInterface.java | 71 ++++++++++++++----- .../MetaTileEntityMonitorScreen.java | 65 ++++++++++++++--- 2 files changed, 111 insertions(+), 25 deletions(-) diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java index 7455688d164..d4950ca4ac7 100644 --- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -19,6 +19,7 @@ import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; import gregtech.common.terminal.app.prospector.widget.WidgetOreList; import net.minecraft.client.Minecraft; @@ -228,7 +229,7 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci } else if (getItemCapability() != null) { items = new ItemStack[getItemCapability().getSlots()]; this.mode = MODE.ITEM; - } else if (getEnergyCapability() != null) { + } else if (getEnergyCapability() != null || getCoverableView() instanceof MetaTileEntityPowerSubstation) { this.mode = MODE.ENERGY; } else if (getMachineCapability() != null) { this.mode = MODE.MACHINE; @@ -579,22 +580,19 @@ private void syncAllInfo() { } } if (this.mode == MODE.ENERGY || (mode == MODE.PROXY && proxyMode[2] > 0)) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate batteries - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } - if (this.getOffsetTimer() % 20 == 0) { // per second + if (this.getOffsetTimer() % 20 == 0) { writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { - packetBuffer.writeLong(energyContainer.getInputPerSec()); - packetBuffer.writeLong(energyContainer.getOutputPerSec()); + packetBuffer.writeLong(pss.getAverageInLastSec() * 20L); + packetBuffer.writeLong(pss.getAverageOutLastSec() * 20L); inputEnergyList.add(energyInputPerDur); outputEnergyList.add(energyOutputPerDur); if (inputEnergyList.size() > 13) { @@ -603,6 +601,33 @@ private void syncAllInfo() { } }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate + // batteries + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + if (this.getOffsetTimer() % 20 == 0) { // per second + writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { + packetBuffer.writeLong(energyContainer.getInputPerSec()); + packetBuffer.writeLong(energyContainer.getOutputPerSec()); + inputEnergyList.add(energyInputPerDur); + outputEnergyList.add(energyOutputPerDur); + if (inputEnergyList.size() > 13) { + inputEnergyList.remove(0); + outputEnergyList.remove(0); + } + }); + } + } } } if (this.mode == MODE.MACHINE || (mode == MODE.PROXY && proxyMode[3] > 0)) { @@ -626,17 +651,28 @@ private void syncAllInfo() { }); } if (this.getOffsetTimer() % 20 == 0) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + } } } } @@ -861,6 +897,7 @@ public boolean canCapabilityAttach() { return getFluidCapability() != null || getItemCapability() != null || getEnergyCapability() != null || + getCoverableView() instanceof MetaTileEntityPowerSubstation || getMachineCapability() != null; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java index a5d37f33c41..46bcafb51d5 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java @@ -202,20 +202,69 @@ private void updateProxyPlugin() { } public int getX() { - if (this.getController() != null) { - if (this.getController().getPos().getX() - this.getPos().getX() != 0) { - return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; - } else { - return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + switch (controller.getFrontFacing().getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } } } return -1; } public int getY() { - if (this.getController() != null) { - return ((MetaTileEntityCentralMonitor) this.getController()).height - - (this.getPos().getY() + 1 - this.getController().getPos().getY()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + EnumFacing facing = controller.getFrontFacing(); + int height = ((MetaTileEntityCentralMonitor) this.getController()).height; + switch (facing.getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return height - + (Math.abs(controller.getPos().getX() - spin.getXOffset() - this.getPos().getX())) - 1; + else + return height - + (Math.abs(controller.getPos().getZ() - spin.getZOffset() - this.getPos().getZ())) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getZ() + spin.getXOffset() * facing.rotateY().getZOffset() - + this.getPos().getZ())) - + 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getX() + spin.getXOffset() * facing.rotateY().getXOffset() - + this.getPos().getX())) - + 1; + } + } } return -1; } From 43bf1a78dbd1a3494d4377a5e65355f3ad404a37 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sun, 10 Mar 2024 17:23:35 -0500 Subject: [PATCH 094/168] Fix server crashes with alarms (#2411) (cherry picked from commit 77ed2e04876c133c8d09ac42ef8a46922c9bd6a2) --- .../electric/MetaTileEntityAlarm.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java index cadf9768286..67751f893e9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java @@ -76,15 +76,17 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return ModularUI.builder(GuiTextures.BACKGROUND, 240, 86) .widget(new LabelWidget(10, 5, getMetaFullName())) .widget(new SelectorWidget(10, 20, 220, 20, - getSounds().stream().map((event) -> event.getSoundName().toString()) + getSounds().stream().map(this::getNameOfSound) .collect(Collectors.toList()), - 0x555555, () -> this.selectedSound.getSoundName().toString(), true).setOnChanged((v) -> { - GregTechAPI.soundManager.stopTileSound(getPos()); + 0x555555, () -> getNameOfSound(this.selectedSound), true).setOnChanged((v) -> { + if (this.getWorld().isRemote) + GregTechAPI.soundManager.stopTileSound(getPos()); SoundEvent newSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); if (this.selectedSound != newSound) { this.selectedSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); this.writeCustomData(GregtechDataCodes.UPDATE_SOUND, - (writer) -> writer.writeResourceLocation(this.selectedSound.getSoundName())); + (writer) -> writer + .writeResourceLocation(getResourceLocationOfSound(this.selectedSound))); } })) .widget(new ImageWidget(10, 54, 220, 20, GuiTextures.DISPLAY)) @@ -168,14 +170,14 @@ public void receiveInitialSyncData(PacketBuffer buf) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(this.isActive); - buf.writeResourceLocation(this.selectedSound.getSoundName()); + buf.writeResourceLocation(getResourceLocationOfSound(this.selectedSound)); buf.writeInt(this.radius); } @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean("isActive", this.isActive); - data.setString("selectedSound", this.selectedSound.getSoundName().toString()); + data.setString("selectedSound", getNameOfSound(this.selectedSound)); data.setInteger("radius", this.radius); return super.writeToNBT(data); } @@ -187,4 +189,12 @@ public void readFromNBT(NBTTagCompound data) { this.radius = data.getInteger("radius"); super.readFromNBT(data); } + + public String getNameOfSound(SoundEvent sound) { + return getResourceLocationOfSound(sound).toString(); + } + + public ResourceLocation getResourceLocationOfSound(SoundEvent sound) { + return SoundEvent.REGISTRY.getNameForObject(sound); + } } From bbf45f2af50b3a869d646619f4bbe18ca198887e Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:21:43 -0400 Subject: [PATCH 095/168] fix pipe capability retrieval logic (#2415) (cherry picked from commit e85169eb34a849d1b56514d4b090cda9080b5bfe) --- .../api/pipenet/tile/TileEntityPipeBase.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index 84897a022e8..7d4fc9015ef 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -335,24 +335,28 @@ public T getCapabilityInternal(Capability capability, @Nullable EnumFacin @Nullable @Override public final T getCapability(@NotNull Capability capability, @Nullable EnumFacing facing) { - boolean isCoverable = capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER; - Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); - T defaultValue; - if (getPipeBlock() == null) - defaultValue = null; - else - defaultValue = getCapabilityInternal(capability, facing); + T pipeCapability = getPipeBlock() == null ? null : getCapabilityInternal(capability, facing); - if (isCoverable) { - return defaultValue; + if (capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER) { + return pipeCapability; } - if (cover == null && facing != null) { - return isConnected(facing) ? defaultValue : null; + + Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); + if (cover == null) { + if (facing == null || isConnected(facing)) { + return pipeCapability; + } + return null; } - if (cover != null) { - return cover.getCapability(capability, defaultValue); + + T coverCapability = cover.getCapability(capability, pipeCapability); + if (coverCapability == pipeCapability) { + if (isConnected(facing)) { + return pipeCapability; + } + return null; } - return defaultValue; + return coverCapability; } @Override From 6e5459debdcb53da7131405a95f555f649625912 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:21:58 -0400 Subject: [PATCH 096/168] fix solar panels not outputting to cables (#2416) (cherry picked from commit fea6440e9852c1e44a88332b568981d2d19c3b7b) --- src/main/java/gregtech/common/covers/CoverSolarPanel.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/covers/CoverSolarPanel.java b/src/main/java/gregtech/common/covers/CoverSolarPanel.java index 7e2e750439a..e972ef560ad 100644 --- a/src/main/java/gregtech/common/covers/CoverSolarPanel.java +++ b/src/main/java/gregtech/common/covers/CoverSolarPanel.java @@ -13,7 +13,6 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -50,10 +49,9 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra public void update() { CoverableView coverable = getCoverableView(); World world = coverable.getWorld(); - BlockPos blockPos = coverable.getPos(); - if (GTUtility.canSeeSunClearly(world, blockPos)) { + if (GTUtility.canSeeSunClearly(world, coverable.getPos())) { IEnergyContainer energyContainer = coverable.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, - null); + getAttachedSide()); if (energyContainer != null) { energyContainer.acceptEnergyFromNetwork(null, EUt, 1); } From 74197e815e69a303031bf3499484c44575228cc3 Mon Sep 17 00:00:00 2001 From: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Sun, 17 Mar 2024 17:12:12 +0100 Subject: [PATCH 097/168] Update GroovyScript & improve material API for groovy (#2389) (cherry picked from commit dc389f8f66475dd741ac96138f926e7f94cb0f70) --- dependencies.gradle | 2 +- .../material/properties/BlastProperty.java | 14 +++-- .../material/CTMaterialHelpers.java | 5 +- .../integration/groovy/GroovyExpansions.java | 42 ++++++++++++++ .../GroovyMaterialBuilderExpansion.java | 36 ++++++++---- .../groovy/GroovyRecipeBuilderExpansion.java | 16 ----- .../groovy/GroovyScriptModule.java | 58 ++++++++++++++++++- 7 files changed, 136 insertions(+), 37 deletions(-) create mode 100644 src/main/java/gregtech/integration/groovy/GroovyExpansions.java delete mode 100644 src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java diff --git a/dependencies.gradle b/dependencies.gradle index 7f2d35d408a..445b5e3963b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,7 +41,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.4.1") { transitive = false } - api("com.cleanroommc:groovyscript:0.7.3") { transitive = false } + api("com.cleanroommc:groovyscript:0.8.0") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 diff --git a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java index 172e0981ac7..61670ea18f9 100644 --- a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java @@ -1,17 +1,18 @@ package gregtech.api.unification.material.properties; +import gregtech.integration.groovy.GroovyScriptModule; + import crafttweaker.CraftTweakerAPI; import org.jetbrains.annotations.NotNull; public class BlastProperty implements IMaterialProperty { /** - * Blast Furnace Temperature of this Material. - * If below 1000K, Primitive Blast Furnace recipes will be also added. + * Blast Furnace Temperature of this Material. If below 1000K, Primitive Blast Furnace recipes will be also added. * If above 1750K, a Hot Ingot and its Vacuum Freezer recipe will be also added. *

- * If a Material with this Property has a Fluid, its temperature - * will be set to this if it is the default Fluid temperature. + * If a Material with this Property has a Fluid, its temperature will be set to this if it is the default Fluid + * temperature. */ private int blastTemperature; @@ -132,7 +133,10 @@ public void verifyProperty(MaterialProperties properties) { public static GasTier validateGasTier(String gasTierName) { if (gasTierName == null) return null; - else if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(GasTier.class, gasTierName, "gas tier"); + } + if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; else if ("MID".equalsIgnoreCase(gasTierName)) return GasTier.MID; else if ("HIGH".equalsIgnoreCase(gasTierName)) return GasTier.HIGH; else if ("HIGHER".equalsIgnoreCase(gasTierName)) return GasTier.HIGHER; diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java index ca5d08a1efa..ed66c077a40 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java @@ -4,6 +4,7 @@ import gregtech.api.fluids.FluidState; import gregtech.api.unification.material.Material; import gregtech.api.unification.stack.MaterialStack; +import gregtech.integration.groovy.GroovyScriptModule; import com.google.common.collect.ImmutableList; import crafttweaker.CraftTweakerAPI; @@ -17,7 +18,9 @@ protected static ImmutableList validateComponentList(MaterialStac protected static FluidState validateFluidState(String fluidTypeName) { if (fluidTypeName == null || fluidTypeName.equals("fluid")) return FluidState.LIQUID; - + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type"); + } if (fluidTypeName.equals("liquid")) return FluidState.LIQUID; if (fluidTypeName.equals("gas")) return FluidState.GAS; if (fluidTypeName.equals("plasma")) return FluidState.PLASMA; diff --git a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java new file mode 100644 index 00000000000..8c23fdf270f --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java @@ -0,0 +1,42 @@ +package gregtech.integration.groovy; + +import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; + +import net.minecraft.util.ResourceLocation; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; + +public class GroovyExpansions { + + public static > RecipeBuilder property(RecipeBuilder builder, String key, + Object value) { + if (!builder.applyProperty(key, value)) { + GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); + } + return builder; + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, ResourceLocation resourceLocation) { + return new Material.Builder(id, resourceLocation); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String domain, String path) { + return materialBuilder(event, id, domain, path); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String s) { + String domain, path; + if (s.contains(":")) { + String[] parts = s.split(":", 2); + domain = parts[0]; + path = parts[1]; + } else { + domain = GroovyScript.getRunConfig().getPackId(); + path = s; + } + return materialBuilder(event, id, new ResourceLocation(domain, path)); + } +} diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index 3f5ea4873f4..f4e30273435 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -8,9 +8,13 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.stack.MaterialStack; import net.minecraft.util.ResourceLocation; +import com.cleanroommc.groovyscript.api.GroovyLog; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + import java.util.ArrayList; import java.util.List; @@ -85,22 +89,30 @@ public static Material.Builder blastTemp(Material.Builder builder, int temp, Str public static Material.Builder blastTemp(Material.Builder builder, int temp, String raw, int eutOverride, int durationOverride, int vacuumEUtOverride, int vacuumDurationOverride) { - BlastProperty.GasTier gasTier = null; - String name = raw.toUpperCase(); - for (BlastProperty.GasTier gasTier1 : BlastProperty.GasTier.VALUES) { - if (gasTier1.name().equals(name)) { - gasTier = gasTier1; - break; - } - } - final BlastProperty.GasTier finalGasTier = gasTier; - if (GroovyScriptModule.validateNonNull(gasTier, () -> "Can't find gas tier for " + name + - " in material builder. Valid values are 'low', 'mid', 'high', 'higher', 'highest'!")) { + BlastProperty.GasTier gasTier = GroovyScriptModule.parseAndValidateEnumValue(BlastProperty.GasTier.class, raw, + "gas tier"); + if (gasTier != null) { return builder.blast(b -> b - .temp(temp, finalGasTier) + .temp(temp, gasTier) .blastStats(eutOverride, durationOverride) .vacuumStats(vacuumEUtOverride, vacuumDurationOverride)); } return builder; } + + public static Material.Builder components(Material.Builder builder, Object... objects) { + ObjectArrayList materialStacks = new ObjectArrayList<>(); + for (Object o : objects) { + if (o instanceof MaterialStack materialStack) { + materialStacks.add(materialStack); + } else if (o instanceof Material material) { + materialStacks.add(new MaterialStack(material, 1)); + } else { + GroovyLog.get() + .error("Material components must be of type Material or MaterialStack, but was of type {}", + o == null ? null : o.getClass()); + } + } + return builder.components(materialStacks.toArray(new MaterialStack[0])); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java deleted file mode 100644 index 90a0dc3753b..00000000000 --- a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java +++ /dev/null @@ -1,16 +0,0 @@ -package gregtech.integration.groovy; - -import gregtech.api.recipes.RecipeBuilder; - -import com.cleanroommc.groovyscript.api.GroovyLog; - -public class GroovyRecipeBuilderExpansion { - - public static > RecipeBuilder property(RecipeBuilder builder, String key, - Object value) { - if (!builder.applyProperty(key, value)) { - GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); - } - return builder; - } -} diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index b6b603bb07e..571261241b2 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -8,6 +8,8 @@ import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.Mods; @@ -35,13 +37,20 @@ import com.cleanroommc.groovyscript.api.GroovyPlugin; import com.cleanroommc.groovyscript.api.IGameObjectHandler; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.event.EventBusType; +import com.cleanroommc.groovyscript.event.GroovyEventManager; import com.cleanroommc.groovyscript.gameobjects.GameObjectHandlerManager; +import com.cleanroommc.groovyscript.helper.EnumHelper; +import com.cleanroommc.groovyscript.sandbox.LoadStage; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; +import groovy.lang.Closure; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; @@ -77,6 +86,18 @@ public static boolean isCurrentlyRunning() { GroovyScript.getSandbox().isRunning(); } + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type) { + T t = EnumHelper.valueOfNullable(clazz, raw, false); + if (t == null) { + GroovyLog.get().error("Can't find {} for {} in material builder. Valid values are {};", + type, + raw, + Arrays.toString(clazz.getEnumConstants())); + return null; + } + return t; + } + public static GroovyContainer getInstance() { return modSupportContainer; } @@ -191,10 +212,42 @@ public static void loadMetaItemBracketHandler() { } @Override - public @NotNull String getModName() { + public @NotNull String getContainerName() { return "GregTech"; } + @Override + public @Nullable ModPropertyContainer createModPropertyContainer() { + return new ModPropertyContainer() { + + public void materialEvent(EventPriority priority, Closure eventListener) { + if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, MaterialEvent.class, + eventListener); + } + + public void materialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + + public void lateMaterialEvent(EventPriority priority, Closure eventListener) { + if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, PostMaterialEvent.class, + eventListener); + } + + public void lateMaterialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + }; + } + @Override public void onCompatLoaded(GroovyContainer groovyContainer) { modSupportContainer = groovyContainer; @@ -213,6 +266,7 @@ public void onCompatLoaded(GroovyContainer groovyContainer) { ExpansionHelper.mixinClass(Material.class, MaterialExpansion.class); ExpansionHelper.mixinClass(Material.class, MaterialPropertyExpansion.class); ExpansionHelper.mixinClass(Material.Builder.class, GroovyMaterialBuilderExpansion.class); - ExpansionHelper.mixinClass(RecipeBuilder.class, GroovyRecipeBuilderExpansion.class); + ExpansionHelper.mixinMethod(RecipeBuilder.class, GroovyExpansions.class, "property"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "materialBuilder"); } } From d92e8e30a8c7846cfbef232272dd186e9b1bcd43 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 24 Mar 2024 10:41:14 -0400 Subject: [PATCH 098/168] allow SMD diodes in low tier diode block recipes (#2423) (cherry picked from commit c2f681f69f7b61c76e4b113263474133993ad056) --- .../java/gregtech/loaders/recipe/MetaTileEntityLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java index 9cb0e321a0e..192c35d1d16 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java @@ -898,7 +898,8 @@ public static void init() { ROTOR); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.ULV, GTValues.HV), "CDC", "DHD", - "PDP", 'H', HULL, 'D', MetaItems.DIODE, 'P', PLATE, 'C', CABLE_QUAD); + "PDP", 'H', HULL, 'D', new UnificationEntry(OrePrefix.component, MarkerMaterials.Component.Diode), 'P', + PLATE, 'C', CABLE_QUAD); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.HV, GTValues.LuV), "CDC", "DHD", "PDP", 'H', HULL, 'D', MetaItems.SMD_DIODE, 'P', PLATE, 'C', CABLE_QUAD); registerMachineRecipe( From 23c7ab694a6149a042d84bf9daf81cde14877c39 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 24 Mar 2024 22:10:19 -0400 Subject: [PATCH 099/168] check for a valid MTE before rendering (#2424) (cherry picked from commit ba69a484403b01e3d87703546c582b61bfe0d596) --- .../client/renderer/handler/MetaTileEntityRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java index 846bcc08860..8e0fe1f6962 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java @@ -94,7 +94,7 @@ public void renderItem(ItemStack rawStack, TransformType transformType) { @Override public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer) { MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(world, pos); - if (metaTileEntity == null) { + if (metaTileEntity == null || !metaTileEntity.isValid()) { return false; } CCRenderState renderState = CCRenderState.instance(); From d40521c292de5f1764a555f1df425541d7fd04bc Mon Sep 17 00:00:00 2001 From: froot <66188216+kumquat-ir@users.noreply.github.com> Date: Wed, 27 Mar 2024 00:16:28 -0700 Subject: [PATCH 100/168] Fix link to GT IMPACT in readme (#2427) (cherry picked from commit 20e61ca2cac5bde02d56827e7a019aa21cb69f5a) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5876b6d1b60..8a4fcfa7209 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Anything else? Sure come to [Discord](https://discord.gg/bWSWuYvURP). ## Credited Works Heating Coil Textures, Wooden Forms, World Accelerators, and the Extreme Combustion Engine are from the **[GregTech: New Horizons Modpack](https://www.curseforge.com/minecraft/modpacks/gt-new-horizons)**. -Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gtimpact.space/)**. +Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gt-impact.github.io/)**. Ender Fluid Link Cover, Auto-Maintenance Hatch, Optical Fiber, and Data Bank Textures are from **[TecTech](https://github.com/Technus/TecTech)**. From d44dcda3428a5408fc410fcd2061c14d2aaa9356 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:16:49 -0600 Subject: [PATCH 101/168] Fix fluid drilling rig display units (#2417) (cherry picked from commit ad8275f17f3f735867f65ed40ec5c09b76d4309b) --- .../multi/electric/MetaTileEntityFluidDrill.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java index a1501dd6f65..dca07a39e5f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java @@ -184,7 +184,7 @@ protected void addDisplayText(List textList) { TextFormatting.BLUE, TextFormattingUtil.formatNumbers( minerLogic.getFluidToProduce() * 20L / FluidDrillLogic.MAX_PROGRESS) + - " L/t"); + " L/s"); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.fluid_rig.fluid_amount", From a7186066d9e2c7b07d89d638b939417936fc37a5 Mon Sep 17 00:00:00 2001 From: iouter <62897714+iouter@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:17:15 +0800 Subject: [PATCH 102/168] Update zh_cn.lang (#2413) (cherry picked from commit db02d99d491e35d00740e338e1feda5046ca7458) --- .../resources/assets/gregtech/lang/zh_cn.lang | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index afd9ee25e54..f47285403cf 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -112,7 +112,7 @@ gregtech.waila.progress_computation=计算进度:%s / %s gregtech.multiblock.title=多方块结构 gregtech.multiblock.primitive_blast_furnace.bronze.description=土高炉是(PBF)是个多方块结构。尽管它不是很快,却能在游戏前期为你的发展提供钢材。 -gregtech.multiblock.coke_oven.description=焦炉是个多方块结构,用于在早期生产焦炭和杂酚油。无需燃料即可工作,内部至多可容纳32桶杂酚油。其存储可通过焦炉仓进行访问。 +gregtech.multiblock.coke_oven.description=焦炉是一种多方块结构,用于在早期生产焦煤和杂酚油,无需燃料即可工作,内部至多可容纳 32 桶杂酚油。其存储可通过焦炉仓进行访问。 gregtech.multiblock.vacuum_freezer.description=真空冷冻机是个多方块结构,主要用于热锭冷却。此外,它还可以冻结水等其他物质。 gregtech.multiblock.implosion_compressor.description=聚爆压缩机是个多方块结构,能够借助炸药将宝石粉转化为相应的宝石。 gregtech.multiblock.pyrolyse_oven.description=热解炉是种用于将原木处理为木炭、杂酚油、灰烬或重油的多方块结构。 @@ -852,7 +852,7 @@ metaitem.cover.item.voiding.advanced.tooltip=作§f覆盖板§7时允许按数 metaitem.cover.storage.name=存储覆盖板 metaitem.cover.storage.tooltip=给零碎的小玩意准备的小型存储空间 metaitem.cover.maintenance.detector.name=维护需求覆盖板 -metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7输出红石信号。 +metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7时发出红石信号。 metaitem.cover.facade.name=%s伪装板 metaitem.cover.facade.tooltip=可作为§f覆盖板§7加装装饰性套壳。 @@ -1008,6 +1008,9 @@ item.gt.tool.screwdriver_lv.name=%s螺丝刀(LV) item.gt.tool.screwdriver_lv.tooltip=§8调整覆盖板和机器 item.gt.tool.plunger.name=%s搋子 item.gt.tool.plunger.tooltip=§8从机器中抽除流体 +item.gt.tool.wire_cutter_lv.name=%s剪线钳(LV) +item.gt.tool.wire_cutter_hv.name=%s剪线钳(HV) +item.gt.tool.wire_cutter_iv.name=%s剪线钳(IV) item.gt.tool.tooltip.crafting_uses=§a合成耐久度:%s @@ -2348,6 +2351,17 @@ tile.treated_wood_fence.name=防腐木栅栏 tile.rubber_wood_fence_gate.name=橡胶木栅栏门 tile.treated_wood_fence_gate.name=防腐木栅栏门 +tile.gt_explosive.breaking_tooltip=破坏它会引爆火药,潜行挖掘以重新拾取 +tile.gt_explosive.lighting_tooltip=无法用红石信号引爆 + +tile.powderbarrel.name=火药桶 +tile.powderbarrel.drops_tooltip=爆炸范围略大于TNT,所有被摧毁的方块都会掉落 +entity.Powderbarrel.name=火药桶 + +tile.itnt.name=工业TNT +tile.itnt.drops_tooltip=爆炸范围比TNT大得多,所有被摧毁的方块都会掉落 +entity.ITNT.name=工业TNT + tile.brittle_charcoal.name=脆木炭块 tile.brittle_charcoal.tooltip.1=产自木炭堆点火器。 tile.brittle_charcoal.tooltip.2=采掘可掉落木炭。 @@ -4410,7 +4424,7 @@ gregtech.machine.world_accelerator.zpm.name=精英世界加速器 III gregtech.machine.world_accelerator.zpm.tooltip=“时间之§m瓶§r”§7方块 gregtech.machine.world_accelerator.uv.name=终极世界加速器 gregtech.machine.world_accelerator.uv.tooltip=时间扭曲者 -gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§r或§f随机刻§7模式中切换。 +gregtech.machine.world_accelerator.description=使用§f螺丝刀§7在§f方块实体§7或§f随机刻§7模式中切换。 gregtech.machine.world_accelerator.power_usage=§7在随机刻模式下最多使用§f%dA,§7在方块实体模式下最多使用§f%dA 。 gregtech.machine.world_accelerator.acceleration=§d加速倍率: §f%dx gregtech.machine.world_accelerator.working_area=§b作用范围: @@ -5248,15 +5262,27 @@ gregtech.machine.laser_hatch.tooltip2=§c激光传导线缆必须直线摆放! gregtech.machine.fluid_tank.max_multiblock=多方块结构最大尺寸:%,dx%,dx%,d gregtech.machine.fluid_tank.fluid=含有%s mB%s -gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +# ME Parts +gregtech.machine.me_import_item_bus.name=ME输入总线 +gregtech.machine.me.item_import.tooltip=从ME网络提取指定物品 +gregtech.machine.me_stocking_item_bus.name=ME库存输入总线 +gregtech.machine.me.stocking_item.tooltip=直接从ME网络抽取物品 +gregtech.machine.me.stocking_item.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种物品,每5秒更新一次。 +gregtech.machine.me_import_item_hatch.configs.tooltip=可标记16种物品 +gregtech.machine.me_import_fluid_hatch.name=ME输入仓 +gregtech.machine.me.fluid_import.tooltip=从ME网络提取指定流体 +gregtech.machine.me_stocking_fluid_hatch.name=ME库存输入仓 +gregtech.machine.me.stocking_fluid.tooltip=直接从ME网络抽取流体 +gregtech.machine.me.stocking_fluid.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种流体,每5秒更新一次。 +gregtech.machine.me_import_fluid_hatch.configs.tooltip=可标记16种流体 gregtech.machine.me_export_item_bus.name=ME输出总线 -gregtech.machine.me_import_fluid_hatch.name=ME库存输入仓 -gregtech.machine.me_import_item_bus.name=ME库存输入总线 -gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中。 -gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中。 -gregtech.machine.me.fluid_import.tooltip=自动从ME网络获取流体。 -gregtech.machine.me.item_import.tooltip=自动从ME网络获取物品。 -gregtech.machine.me.export.tooltip=在连接到ME网络之前,它具有无限容量。 +gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中 +gregtech.machine.me.item_export.tooltip.2=可以缓存无限数量的物品 +gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中 +gregtech.machine.me.fluid_export.tooltip.2=可以缓存无限数量的流体 +gregtech.machine.me.stocking_auto_pull_enabled=ME自动拉取已启用 +gregtech.machine.me.stocking_auto_pull_disabled=ME自动拉取已禁用 # Universal tooltips gregtech.universal.tooltip.voltage_in=§a输入电压:§f%,d EU/t(%s§f) @@ -5279,7 +5305,7 @@ gregtech.universal.tooltip.item_stored=§d内含物品:§f%2$,d + %3$,d 个%1$ gregtech.universal.tooltip.item_transfer_rate=§b传输速率:§f%,d件物品/s gregtech.universal.tooltip.item_transfer_rate_stacks=§b传输速率:§f%,d组物品/s gregtech.universal.tooltip.fluid_storage_capacity=§9流体容量:§f%,d L -gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§r共§f%d§7个流体槽,每个§f%dL§7 +gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§7共§f%d§7个流体槽,每个§f%dL§7 gregtech.universal.tooltip.fluid_stored=§d内含流体:§f%2$,d L %1$s gregtech.universal.tooltip.fluid_transfer_rate=§b传输速率:§f%,d L/t gregtech.universal.tooltip.parallel=§d最大并行:§f%d @@ -5397,8 +5423,12 @@ gregtech.gui.me_network.offline=网络状态:§4离线§r gregtech.gui.waiting_list=发送队列: gregtech.gui.config_slot=§f配置槽位§r gregtech.gui.config_slot.set=§7点击§b设置/选择§7配置槽位。§r +gregtech.gui.config_slot.set_only=§7点击§b设置§7配置槽位。§r gregtech.gui.config_slot.scroll=§7使用滚轮§a切换§7配置数。§r gregtech.gui.config_slot.remove=§7右击§4清除§7配置槽位。§r +gregtech.gui.config_slot.auto_pull_managed=§4禁用:§7由ME自动拉取管理 +gregtech.gui.me_bus.extra_slot=额外槽位/n§7在这里放置配方的额外物品,例如模具或透镜 +gregtech.gui.me_bus.auto_pull_button=单击以切换ME自动拉取模式 gregtech.gui.alarm.radius=半径: From 68ff661f3e76f73404037e81b2e673de1edc7d5a Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:08:12 -0700 Subject: [PATCH 103/168] Allow Data Stick to copy-paste ME bus settings (#2419) (cherry picked from commit 111326a1222de0cd03b18f1cd8a73163110f88cc) --- .../api/capability/IDataStickIntractable.java | 11 ++++ .../api/metatileentity/MetaTileEntity.java | 43 ++++++++++-- .../appeng/MetaTileEntityMEInputBus.java | 65 ++++++++++++++++++- .../appeng/MetaTileEntityMEInputHatch.java | 58 ++++++++++++++++- .../appeng/MetaTileEntityMEStockingBus.java | 28 ++++++++ .../appeng/MetaTileEntityMEStockingHatch.java | 26 ++++++++ .../resources/assets/gregtech/lang/en_us.lang | 5 ++ 7 files changed, 227 insertions(+), 9 deletions(-) create mode 100644 src/main/java/gregtech/api/capability/IDataStickIntractable.java diff --git a/src/main/java/gregtech/api/capability/IDataStickIntractable.java b/src/main/java/gregtech/api/capability/IDataStickIntractable.java new file mode 100644 index 00000000000..4b9d36ee6ff --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDataStickIntractable.java @@ -0,0 +1,11 @@ +package gregtech.api.capability; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IDataStickIntractable { + + void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick); + + boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick); +} diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index b654a1dc397..bef1134a3d0 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -6,9 +6,18 @@ import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IEnergyContainer; -import gregtech.api.capability.impl.*; -import gregtech.api.cover.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.FluidHandlerProxy; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerProxy; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.cover.Cover; +import gregtech.api.cover.CoverHolder; +import gregtech.api.cover.CoverRayTracer; +import gregtech.api.cover.CoverSaveHandler; +import gregtech.api.cover.CoverUtil; import gregtech.api.gui.ModularUI; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.items.toolitem.ToolClasses; @@ -23,6 +32,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; +import gregtech.common.items.MetaItems; import net.minecraft.block.Block; import net.minecraft.block.state.BlockFaceShape; @@ -38,7 +48,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; @@ -78,7 +94,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -436,6 +456,12 @@ public final void onCoverLeftClick(EntityPlayer playerIn, CuboidRayTraceResult r public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { ItemStack heldStack = playerIn.getHeldItem(hand); + if (this instanceof IDataStickIntractable dsi) { + if (MetaItems.TOOL_DATA_STICK.isItemEqual(heldStack) && dsi.onDataStickRightClick(playerIn, heldStack)) { + return true; + } + } + if (!playerIn.isSneaking() && openGUIOnRightClick()) { if (getWorld() != null && !getWorld().isRemote) { MetaTileEntityUIFactory.INSTANCE.openUI(getHolder(), (EntityPlayerMP) playerIn); @@ -587,7 +613,14 @@ public boolean onHardHammerClick(EntityPlayer playerIn, EnumHand hand, EnumFacin return true; } - public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) {} + public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (this instanceof IDataStickIntractable dsi) { + ItemStack stack = player.getHeldItemMainhand(); + if (MetaItems.TOOL_DATA_STICK.isItemEqual(stack)) { + dsi.onDataStickLeftClick(player, stack); + } + } + } /** * @return true if the player must sneak to rotate this metatileentity, otherwise false diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 1076de705e9..8c939df5a72 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IGhostSlotConfigurable; import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.GhostCircuitItemStackHandler; @@ -54,15 +55,15 @@ public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart, - IGhostSlotConfigurable { + IGhostSlotConfigurable, IDataStickIntractable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; private boolean workingEnabled = true; protected ExportOnlyAEItemList aeItemHandler; - private GhostCircuitItemStackHandler circuitInventory; - private NotifiableItemStackHandler extraSlotInventory; + protected GhostCircuitItemStackHandler circuitInventory; + protected NotifiableItemStackHandler extraSlotInventory; private ItemHandlerList actualImportItems; public MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId) { @@ -318,6 +319,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -346,4 +348,61 @@ public void setGhostCircuitConfig(int config) { markDirty(); } } + + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputBus", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.item_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } + + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeItemHandler.getInventory()[i]; + IAEItemStack config = slot.getConfig(); + if (config == null) { + continue; + } + NBTTagCompound stackNbt = new NBTTagCompound(); + config.getDefinition().writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); + } + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } + + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputBus")) { + return false; + } + readConfigFromTag(tag.getCompoundTag("MEInputBus")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } + + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeItemHandler.getInventory()[i].setConfig(WrappedItemStack.fromNBT(configTag)); + } else { + this.aeItemHandler.getInventory()[i].setConfig(null); + } + } + } + if (tag.hasKey("GhostCircuit")) { + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index c864cecff64..319498b12e8 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; @@ -26,6 +27,7 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.IFluidTank; @@ -44,7 +46,7 @@ import java.util.List; public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { + implements IMultiblockAbilityPart, IDataStickIntractable { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; @@ -257,6 +259,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -269,4 +272,57 @@ public MultiblockAbility getAbility() { public void registerAbilities(List list) { list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } + + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputHatch", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.fluid_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } + + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeFluidHandler.getInventory()[i]; + IAEFluidStack config = slot.getConfig(); + if (config == null) { + continue; + } + NBTTagCompound stackNbt = new NBTTagCompound(); + config.writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); + } + return tag; + } + + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputHatch")) { + return false; + } + readConfigFromTag(tag.getCompoundTag("MEInputHatch")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } + + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeFluidHandler.getInventory()[i].setConfig(WrappedFluidStack.fromNBT(configTag)); + } else { + this.aeFluidHandler.getInventory()[i].setConfig(null); + } + } + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java index 99928574f82..f8bd7a5850a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -358,10 +358,38 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { private final MetaTileEntityMEStockingBus holder; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java index 1693ece229b..fcc9e1e7d12 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -263,10 +263,36 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip")); tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 3cd60ebeed0..17ecb6241af 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5283,6 +5283,11 @@ gregtech.machine.me.fluid_export.tooltip=Stores fluids directly into the ME netw gregtech.machine.me.fluid_export.tooltip.2=Can cache an infinite amount of fluid gregtech.machine.me.stocking_auto_pull_enabled=Auto-Pull Enabled gregtech.machine.me.stocking_auto_pull_disabled=Auto-Pull Disabled +gregtech.machine.me.copy_paste.tooltip=Left-click with Data Stick to copy settings, right-click to apply +gregtech.machine.me.import_copy_settings=Saved settings to Data Stick +gregtech.machine.me.import_paste_settings=Applied settings from Data Stick +gregtech.machine.me.item_import.data_stick.name=§oME Input Bus Configuration Data +gregtech.machine.me.fluid_import.data_stick.name=§oME Input Hatch Configuration Data # Universal tooltips gregtech.universal.tooltip.voltage_in=§aVoltage IN: §f%,d EU/t (%s§f) From 132fc1246d61fd206beff5e607735dd2698a1463 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:09:13 -0700 Subject: [PATCH 104/168] Fix LCE/ECE from parallelizing too much (#2426) (cherry picked from commit aff043cfaa43f8dd44c45fb5de602fa2d3b56282) --- .../api/capability/impl/MultiblockFuelRecipeLogic.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java index 9f93440025c..168ed40c67c 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java @@ -78,6 +78,11 @@ public int getParallelLimit() { return Integer.MAX_VALUE; } + @Override + protected long getMaxParallelVoltage() { + return getMaxVoltage(); + } + /** * Boost the energy production. * Should not change the state of the workable logic. Only read current values. From a5a15436667a8a57473c2a22574b86541176184a Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:00:13 -0400 Subject: [PATCH 105/168] add ItemStack inputNBT method (#2431) (cherry picked from commit e6cc4930ca204be09d0721198b274f344c0add4e) --- .../gregtech/api/recipes/RecipeBuilder.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index 87175224c5d..980176fdb5b 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -276,20 +276,20 @@ public R inputNBT(OrePrefix orePrefix, Material material, int count, NBTMatcher } public R inputNBT(Item item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item)), matcher, condition); + return inputNBT(new ItemStack(item), matcher, condition); } public R inputNBT(Item item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item), count), matcher, condition); + return inputNBT(new ItemStack(item, count), matcher, condition); } public R inputNBT(Item item, int count, int meta, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, meta)), matcher, condition); + return inputNBT(new ItemStack(item, count, meta), matcher, condition); } public R inputNBT(Item item, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(item, count, GTValues.W), matcher, condition); } public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { @@ -297,28 +297,40 @@ public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { } public R inputNBT(Block block, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count)), matcher, condition); + return inputNBT(new ItemStack(block, count), matcher, condition); } public R inputNBT(Block block, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(block, count, GTValues.W), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm(count)), matcher, condition); + return inputNBT(item.getStackForm(count), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm()), matcher, condition); + return inputNBT(item.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm()), matcher, condition); + return inputNBT(mte.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, int amount, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm(amount)), matcher, condition); + return inputNBT(mte.getStackForm(amount), matcher, condition); + } + + /** + * NBT tags are stripped from the input stack and are not automatically checked. + * + * @param stack the itemstack to input. + * @param matcher the matcher for the stack's nbt + * @param condition the condition for the stack's nbt + * @return this + */ + public R inputNBT(@NotNull ItemStack stack, NBTMatcher matcher, NBTCondition condition) { + return inputNBT(new GTRecipeItemInput(stack), matcher, condition); } public R inputs(ItemStack... inputs) { From 8e5bb132fefe7fc99ce3745b270bcde5ffbc6d12 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:40:03 -0400 Subject: [PATCH 106/168] fix MTE block opacity (#2440) (cherry picked from commit 323d93a91c390fd12d11bf2971acb6255fcca120) --- .../java/gregtech/api/block/machines/BlockMachine.java | 2 +- .../gregtech/api/block/machines/MachineItemBlock.java | 2 +- .../metatileentities/storage/MetaTileEntityCrate.java | 6 ------ .../metatileentities/storage/MetaTileEntityDrum.java | 10 ---------- 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index cc2e4dbe3a0..845fb5f1969 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -481,7 +481,7 @@ public int getLightValue(@NotNull IBlockState state, @NotNull IBlockAccess world public int getLightOpacity(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos) { // since it is called on neighbor blocks MetaTileEntity metaTileEntity = getMetaTileEntity(world, pos); - return metaTileEntity == null ? 0 : metaTileEntity.getLightOpacity(); + return metaTileEntity == null ? 255 : metaTileEntity.getLightOpacity(); } @Override diff --git a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java index 1186eaefa7c..32a12a113af 100644 --- a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java +++ b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java @@ -91,7 +91,7 @@ public boolean placeBlockAt(@NotNull ItemStack stack, @NotNull EntityPlayer play // prevent rendering glitch before meta tile entity sync to client, but after block placement // set opaque property on the placing on block, instead during set of meta tile entity boolean superVal = super.placeBlockAt(stack, player, world, pos, side, hitX, hitY, hitZ, - newState.withProperty(BlockMachine.OPAQUE, metaTileEntity != null && metaTileEntity.isOpaqueCube())); + newState.withProperty(BlockMachine.OPAQUE, metaTileEntity == null || metaTileEntity.isOpaqueCube())); if (superVal && !world.isRemote) { BlockPos possiblePipe = pos.offset(side.getOpposite()); Block block = world.getBlockState(possiblePipe).getBlock(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index 1a7d5c00752..c4737df2628 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -39,7 +39,6 @@ import java.util.List; import static gregtech.api.capability.GregtechDataCodes.IS_TAPED; -import static gregtech.api.capability.GregtechDataCodes.TAG_KEY_PAINTING_COLOR; public class MetaTileEntityCrate extends MetaTileEntity { @@ -66,11 +65,6 @@ public boolean hasFrontFacing() { return false; } - @Override - public int getLightOpacity() { - return 1; - } - @Override public String getHarvestTool() { return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index 321012fcf8f..7a5ef5b4d38 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -71,16 +71,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityDrum(metaTileEntityId, material, tankSize); } - @Override - public int getLightOpacity() { - return 1; - } - - @Override - public boolean isOpaqueCube() { - return false; - } - @Override public String getHarvestTool() { return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; From 7d4a2434af5bfb27b73923230e8ea31b8595dad8 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:40:16 -0400 Subject: [PATCH 107/168] minor allocation optimization for GTUtility#canSeeSunClearly (#2441) (cherry picked from commit 1e98892e6ec28b81d5930fa6a9c0bc62b2ff41cf) --- src/main/java/gregtech/api/util/GTUtility.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index bf88330a68b..b4e3c75aeb8 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -699,15 +699,19 @@ public static MetaTileEntity getMetaTileEntity(ItemStack stack) { return GregTechAPI.MTE_REGISTRY.getObjectById(stack.getItemDamage()); } - public static boolean canSeeSunClearly(World world, BlockPos blockPos) { - if (!world.canSeeSky(blockPos.up())) { + /** + * @param world the world containing the block + * @param blockPos the position of the block to check + * @return if the block can see the sun clearly + */ + public static boolean canSeeSunClearly(@NotNull World world, @NotNull BlockPos blockPos) { + BlockPos up = blockPos.up(); + if (!world.canSeeSky(up)) { return false; } - Biome biome = world.getBiome(blockPos.up()); - if (world.isRaining()) { - if (biome.canRain() || biome.getEnableSnow()) { - return false; - } + Biome biome = world.getBiome(up); + if (world.isRaining() && (biome.canRain() || biome.getEnableSnow())) { + return false; } Set biomeTypes = BiomeDictionary.getTypes(biome); if (biomeTypes.contains(BiomeDictionary.Type.END)) { From 902d75d0deaa5a5bd6ae004957b51e7ac3155088 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:40:58 -0700 Subject: [PATCH 108/168] Fix potential MetaTileEntity NPE when calling a server side method on client (#2437) (cherry picked from commit 1e4ca34ea0b1ed2fc38f9a05c05b5f97d0bd4f5c) --- src/main/java/gregtech/api/metatileentity/MetaTileEntity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index bef1134a3d0..5488145709a 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -789,18 +789,20 @@ private void updateLightValue() { } public void update() { - if (!allowTickAcceleration()) { + if (!getWorld().isRemote && !allowTickAcceleration()) { int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); if (currentTick == lastTick) { return; } lastTick = currentTick; } + for (MTETrait mteTrait : this.mteTraits.values()) { if (shouldUpdate(mteTrait)) { mteTrait.update(); } } + if (!getWorld().isRemote) { updateCovers(); } else { From 95741c7c656b65fe5c900e9b04304816dd3b52f7 Mon Sep 17 00:00:00 2001 From: tier940 Date: Fri, 5 Apr 2024 06:42:36 +0900 Subject: [PATCH 109/168] Add stairsRecipeName (#2435) (cherry picked from commit a27b30bb375376c88b62625094cd1e6c43d9eb38) --- .../java/gregtech/loaders/WoodTypeEntry.java | 36 +++++++++++-------- .../loaders/recipe/WoodRecipeLoader.java | 20 ++++++----- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/loaders/WoodTypeEntry.java b/src/main/java/gregtech/loaders/WoodTypeEntry.java index 7a086b1b55e..dd75a07cdb7 100644 --- a/src/main/java/gregtech/loaders/WoodTypeEntry.java +++ b/src/main/java/gregtech/loaders/WoodTypeEntry.java @@ -52,6 +52,8 @@ public final class WoodTypeEntry { public final String fenceGateRecipeName; @NotNull public final ItemStack stairs; + @Nullable + public final String stairsRecipeName; public final boolean addStairsCraftingRecipe; @NotNull public final ItemStack boat; @@ -83,13 +85,14 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull @NotNull ItemStack slab, @Nullable String slabRecipeName, boolean addSlabCraftingRecipe, @NotNull ItemStack fence, @Nullable String fenceRecipeName, @NotNull ItemStack fenceGate, @Nullable String fenceGateRecipeName, @NotNull ItemStack stairs, - boolean addStairsCraftingRecipe, @NotNull ItemStack boat, @Nullable String boatRecipeName, - @Nullable Material material, boolean addLogOreDict, boolean addPlanksOreDict, - boolean addDoorsOreDict, boolean addSlabsOreDict, boolean addFencesOreDict, - boolean addFenceGatesOreDict, boolean addStairsOreDict, boolean addPlanksUnificationInfo, - boolean addDoorsUnificationInfo, boolean addSlabsUnificationInfo, - boolean addFencesUnificationInfo, boolean addFenceGatesUnificationInfo, - boolean addStairsUnificationInfo, boolean addBoatsUnificationInfo) { + @Nullable String stairsRecipeName, boolean addStairsCraftingRecipe, @NotNull ItemStack boat, + @Nullable String boatRecipeName, @Nullable Material material, boolean addLogOreDict, + boolean addPlanksOreDict, boolean addDoorsOreDict, boolean addSlabsOreDict, + boolean addFencesOreDict, boolean addFenceGatesOreDict, boolean addStairsOreDict, + boolean addPlanksUnificationInfo, boolean addDoorsUnificationInfo, + boolean addSlabsUnificationInfo, boolean addFencesUnificationInfo, + boolean addFenceGatesUnificationInfo, boolean addStairsUnificationInfo, + boolean addBoatsUnificationInfo) { this.modid = modid; this.woodName = woodName; this.log = log; @@ -107,6 +110,7 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull this.fenceGate = fenceGate; this.fenceGateRecipeName = fenceGateRecipeName; this.stairs = stairs; + this.stairsRecipeName = stairsRecipeName; this.addStairsCraftingRecipe = addStairsCraftingRecipe; this.boat = boat; this.boatRecipeName = boatRecipeName; @@ -153,6 +157,7 @@ public static class Builder { private ItemStack fenceGate = ItemStack.EMPTY; private String fenceGateRecipeName; private ItemStack stairs = ItemStack.EMPTY; + private String stairsRecipeName; private boolean addStairsCraftingRecipe; private ItemStack boat = ItemStack.EMPTY; private String boatRecipeName; @@ -294,11 +299,13 @@ public Builder fenceGate(@NotNull ItemStack fenceGate, @Nullable String fenceGat /** * Add an entry for stairs * - * @param stairs the stairs to add + * @param stairs the stairs to add + * @param stairsRecipeName the recipe name for crafting the stairs * @return this */ - public Builder stairs(@NotNull ItemStack stairs) { + public Builder stairs(@NotNull ItemStack stairs, @Nullable String stairsRecipeName) { this.stairs = stairs; + this.stairsRecipeName = stairsRecipeName; return this; } @@ -410,12 +417,11 @@ public WoodTypeEntry build() { Preconditions.checkArgument(!planks.isEmpty(), "Planks cannot be empty."); return new WoodTypeEntry(modid, woodName, log, removeCharcoalRecipe, addCharcoalRecipe, planks, planksRecipeName, door, doorRecipeName, slab, slabRecipeName, addSlabsCraftingRecipe, fence, - fenceRecipeName, - fenceGate, fenceGateRecipeName, stairs, addStairsCraftingRecipe, boat, boatRecipeName, material, - addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, addFencesOreDict, - addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, addDoorsUnificationInfo, - addSlabsUnificationInfo, addFencesUnificationInfo, addFenceGatesUnificationInfo, - addStairsUnificationInfo, addBoatsUnificationInfo); + fenceRecipeName, fenceGate, fenceGateRecipeName, stairs, stairsRecipeName, addStairsCraftingRecipe, + boat, boatRecipeName, material, addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, + addFencesOreDict, addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, + addDoorsUnificationInfo, addSlabsUnificationInfo, addFencesUnificationInfo, + addFenceGatesUnificationInfo, addStairsUnificationInfo, addBoatsUnificationInfo); } } } diff --git a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java index c790b6c809d..953649972d8 100644 --- a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java @@ -49,7 +49,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB), "oak_wooden_slab") .fence(new ItemStack(Blocks.OAK_FENCE), "fence") .fenceGate(new ItemStack(Blocks.OAK_FENCE_GATE), "fence_gate") - .stairs(new ItemStack(Blocks.OAK_STAIRS)) + .stairs(new ItemStack(Blocks.OAK_STAIRS), "oak_stairs") .boat(new ItemStack(Items.BOAT), "boat") .registerAllUnificationInfo() .build(), @@ -60,7 +60,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 1), "spruce_wooden_slab") .fence(new ItemStack(Blocks.SPRUCE_FENCE), "spruce_fence") .fenceGate(new ItemStack(Blocks.SPRUCE_FENCE_GATE), "spruce_fence_gate") - .stairs(new ItemStack(Blocks.SPRUCE_STAIRS)) + .stairs(new ItemStack(Blocks.SPRUCE_STAIRS), "spruce_stairs") .boat(new ItemStack(Items.SPRUCE_BOAT), "spruce_boat") .registerAllUnificationInfo() .build(), @@ -71,7 +71,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 2), "birch_wooden_slab") .fence(new ItemStack(Blocks.BIRCH_FENCE), "birch_fence") .fenceGate(new ItemStack(Blocks.BIRCH_FENCE_GATE), "birch_fence_gate") - .stairs(new ItemStack(Blocks.BIRCH_STAIRS)) + .stairs(new ItemStack(Blocks.BIRCH_STAIRS), "birch_stairs") .boat(new ItemStack(Items.BIRCH_BOAT), "birch_boat") .registerAllUnificationInfo() .build(), @@ -82,7 +82,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 3), "jungle_wooden_slab") .fence(new ItemStack(Blocks.JUNGLE_FENCE), "jungle_fence") .fenceGate(new ItemStack(Blocks.JUNGLE_FENCE_GATE), "jungle_fence_gate") - .stairs(new ItemStack(Blocks.JUNGLE_STAIRS)) + .stairs(new ItemStack(Blocks.JUNGLE_STAIRS), "jungle_stairs") .boat(new ItemStack(Items.JUNGLE_BOAT), "jungle_boat") .registerAllUnificationInfo() .build(), @@ -93,7 +93,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 4), "acacia_wooden_slab") .fence(new ItemStack(Blocks.ACACIA_FENCE), "acacia_fence") .fenceGate(new ItemStack(Blocks.ACACIA_FENCE_GATE), "acacia_fence_gate") - .stairs(new ItemStack(Blocks.ACACIA_STAIRS)) + .stairs(new ItemStack(Blocks.ACACIA_STAIRS), "acacia_stairs") .boat(new ItemStack(Items.ACACIA_BOAT), "acacia_boat") .registerAllUnificationInfo() .build(), @@ -104,7 +104,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 5), "dark_oak_wooden_slab") .fence(new ItemStack(Blocks.DARK_OAK_FENCE), "dark_oak_fence") .fenceGate(new ItemStack(Blocks.DARK_OAK_FENCE_GATE), "dark_oak_fence_gate") - .stairs(new ItemStack(Blocks.DARK_OAK_STAIRS)) + .stairs(new ItemStack(Blocks.DARK_OAK_STAIRS), "dark_oak_stairs") .boat(new ItemStack(Items.DARK_OAK_BOAT), "dark_oak_boat") .registerAllUnificationInfo() .build(), @@ -115,7 +115,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(MetaBlocks.WOOD_SLAB), null).addSlabRecipe() .fence(new ItemStack(MetaBlocks.RUBBER_WOOD_FENCE), null) .fenceGate(new ItemStack(MetaBlocks.RUBBER_WOOD_FENCE_GATE), null) - .stairs(new ItemStack(MetaBlocks.RUBBER_WOOD_STAIRS)).addStairsRecipe() + .stairs(new ItemStack(MetaBlocks.RUBBER_WOOD_STAIRS), null).addStairsRecipe() .boat(MetaItems.RUBBER_WOOD_BOAT.getStackForm(), null) .registerAllOres() .registerAllUnificationInfo() @@ -126,7 +126,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(MetaBlocks.WOOD_SLAB, 1, 1), null).addSlabRecipe() .fence(new ItemStack(MetaBlocks.TREATED_WOOD_FENCE), null) .fenceGate(new ItemStack(MetaBlocks.TREATED_WOOD_FENCE_GATE), null) - .stairs(new ItemStack(MetaBlocks.TREATED_WOOD_STAIRS)).addStairsRecipe() + .stairs(new ItemStack(MetaBlocks.TREATED_WOOD_STAIRS), null).addStairsRecipe() .boat(MetaItems.TREATED_WOOD_BOAT.getStackForm(), null) .material(TreatedWood) .registerAllOres() @@ -326,8 +326,10 @@ public static void registerWoodTypeRecipe(@NotNull WoodTypeEntry entry) { // stairs if (!entry.stairs.isEmpty()) { + final boolean hasStairRecipe = entry.stairsRecipeName != null; if (entry.addStairsCraftingRecipe) { - ModHandler.addShapedRecipe(name + "_stairs", GTUtility.copy(4, entry.stairs), + ModHandler.addShapedRecipe(hasStairRecipe ? entry.stairsRecipeName : name + "_stairs", + GTUtility.copy(4, entry.stairs), "P ", "PP ", "PPP", 'P', entry.planks.copy()); } From 8830bfbd53aeed0c360bdadc3b24f0a6087c86cd Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:58:19 -0700 Subject: [PATCH 110/168] Improve the Quantum Storage Renderer (#2318) (cherry picked from commit 06938f05be5bccf67e54e0bb5c9d7b7384c4c75e) --- .../api/gui/resources/TextTexture.java | 29 ++++- .../renderer/handler/MetaTileEntityTESR.java | 4 +- .../custom/QuantumStorageRenderer.java | 121 +++++++++++++----- .../java/gregtech/common/ConfigHolder.java | 6 +- .../storage/MetaTileEntityCreativeChest.java | 2 +- .../storage/MetaTileEntityCreativeTank.java | 2 +- .../storage/MetaTileEntityQuantumChest.java | 2 +- .../storage/MetaTileEntityQuantumTank.java | 18 ++- 8 files changed, 134 insertions(+), 50 deletions(-) diff --git a/src/main/java/gregtech/api/gui/resources/TextTexture.java b/src/main/java/gregtech/api/gui/resources/TextTexture.java index 19928d07c8b..2750890d749 100644 --- a/src/main/java/gregtech/api/gui/resources/TextTexture.java +++ b/src/main/java/gregtech/api/gui/resources/TextTexture.java @@ -20,16 +20,26 @@ public class TextTexture implements IGuiTexture { public TextType type; @SideOnly(Side.CLIENT) private List texts; + private final boolean isClient = FMLCommonHandler.instance().getSide().isClient(); public TextTexture(String text, int color) { this.color = color; this.type = TextType.NORMAL; - if (FMLCommonHandler.instance().getSide().isClient()) { + if (isClient) { this.text = I18n.format(text); texts = Collections.singletonList(this.text); } } + public TextTexture() { + this.color = 0xFFFFFF; + this.type = TextType.NORMAL; + this.text = ""; + + if (isClient) + this.texts = Collections.singletonList(this.text); + } + public TextTexture setColor(int color) { this.color = color; return this; @@ -42,11 +52,18 @@ public TextTexture setDropShadow(boolean dropShadow) { public TextTexture setWidth(int width) { this.width = width; - if (FMLCommonHandler.instance().getSide().isClient()) { - if (this.width > 0) { - texts = Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(text, width); - } else { - texts = Collections.singletonList(text); + return this; + } + + public TextTexture setText(String text) { + if (!this.text.equals(text)) { + this.text = text; + if (isClient) { + if (this.width > 0) { + texts = Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(text, width); + } else { + texts = Collections.singletonList(text); + } } } return this; diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java index c22b454748a..04f29382669 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java @@ -46,12 +46,12 @@ public void render(@NotNull MetaTileEntityHolder te, double x, double y, double buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); MetaTileEntity metaTileEntity = te.getMetaTileEntity(); - if (metaTileEntity instanceof IFastRenderMetaTileEntity) { + if (metaTileEntity instanceof IFastRenderMetaTileEntity fastRender) { CCRenderState renderState = CCRenderState.instance(); renderState.reset(); renderState.bind(buffer); renderState.setBrightness(te.getWorld(), te.getPos()); - ((IFastRenderMetaTileEntity) metaTileEntity).renderMetaTileEntityFast(renderState, + fastRender.renderMetaTileEntityFast(renderState, new Matrix4().translate(x, y, z), partialTicks); } if (metaTileEntity != null) { diff --git a/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java index 7e6485a155d..c5379c4e3af 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java @@ -1,10 +1,13 @@ package gregtech.client.renderer.texture.custom; import gregtech.api.gui.resources.TextTexture; +import gregtech.api.metatileentity.ITieredMetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer.RenderSide; import gregtech.client.utils.RenderUtil; +import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumChest; import net.minecraft.client.Minecraft; @@ -19,6 +22,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidStack; @@ -40,6 +44,8 @@ public class QuantumStorageRenderer implements TextureUtils.IIconRegister { private static final EnumMap boxFacingMap = new EnumMap<>(EnumFacing.class); + private static final TextTexture textRenderer = new TextTexture().setWidth(32); + @SideOnly(Side.CLIENT) private TextureAtlasSprite glassTexture; @@ -62,30 +68,48 @@ public void registerIcons(TextureMap textureMap) { .registerSprite(new ResourceLocation("gregtech:blocks/overlay/machine/overlay_screen_glass")); } - public void renderMachine(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, - EnumFacing frontFacing, int tier) { + public void renderMachine(CCRenderState renderState, + Matrix4 translation, + IVertexOperation[] pipeline, + T mte) { + EnumFacing frontFacing = mte.getFrontFacing(); + int tier = mte.getTier(); Textures.renderFace(renderState, translation, pipeline, frontFacing, glassBox, glassTexture, BlockRenderLayer.CUTOUT_MIPPED); TextureAtlasSprite hullTexture = Textures.VOLTAGE_CASINGS[tier] .getSpriteOnSide(RenderSide.bySide(EnumFacing.NORTH)); - boxFacingMap.keySet().forEach(facing -> { - for (EnumFacing box : EnumFacing.VALUES) { - if ((facing != frontFacing || box != frontFacing) && - (facing != EnumFacing.DOWN || box.getAxis().isVertical())) { // Don't render the front facing - // box from the front, nor allow - // Z-fighting to occur on the - // bottom - Textures.renderFace(renderState, translation, pipeline, facing, boxFacingMap.get(box), hullTexture, - BlockRenderLayer.CUTOUT_MIPPED); - } - } - }); + + for (var facing : boxFacingMap.keySet()) { + // do not render the box at the front face when "facing" is "frontFacing" + if (facing == frontFacing) continue; + + // render when the box face matches facing + Textures.renderFace(renderState, translation, pipeline, facing, boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + + // render when the box face is opposite of facing + Textures.renderFace(renderState, translation, pipeline, facing.getOpposite(), boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + } + + // render the sides of the box that face the front face + if (frontFacing.getAxis() == EnumFacing.Axis.Y) return; + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(EnumFacing.DOWN), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(EnumFacing.UP), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + + EnumFacing facing = frontFacing.rotateYCCW(); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(facing.getOpposite()), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); } public static void renderChestStack(double x, double y, double z, MetaTileEntityQuantumChest machine, ItemStack stack, long count, float partialTicks) { - if (stack.isEmpty() || count == 0) + if (!ConfigHolder.client.enableFancyChestRender || stack.isEmpty() || count == 0) return; float lastBrightnessX = OpenGlHelper.lastBrightnessX; @@ -93,15 +117,19 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity World world = machine.getWorld(); setLightingCorrectly(world, machine.getPos()); EnumFacing frontFacing = machine.getFrontFacing(); - RenderItem itemRenderer = Minecraft.getMinecraft().getRenderItem(); - float tick = world.getWorldTime() + partialTicks; - GlStateManager.pushMatrix(); - GlStateManager.translate(x, y, z); - GlStateManager.translate(0.5D, 0.5D, 0.5D); - GlStateManager.rotate(tick * (float) Math.PI * 2 / 40, 0, 1, 0); - GlStateManager.scale(0.6f, 0.6f, 0.6f); - itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); - GlStateManager.popMatrix(); + + if (canRender(x, y, z, 8 * + MathHelper.clamp((double) Minecraft.getMinecraft().gameSettings.renderDistanceChunks / 8, 1.0, 2.5))) { + RenderItem itemRenderer = Minecraft.getMinecraft().getRenderItem(); + float tick = world.getWorldTime() + partialTicks; + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + GlStateManager.translate(0.5D, 0.5D, 0.5D); + GlStateManager.rotate(tick * (float) Math.PI * 2 / 40, 0, 1, 0); + GlStateManager.scale(0.6f, 0.6f, 0.6f); + itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); + GlStateManager.popMatrix(); + } OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); renderAmountText(x, y, z, count, frontFacing); @@ -110,20 +138,20 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity public static void renderTankFluid(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, FluidTank tank, IBlockAccess world, BlockPos pos, EnumFacing frontFacing) { - float lastBrightnessX = OpenGlHelper.lastBrightnessX; - float lastBrightnessY = OpenGlHelper.lastBrightnessY; + FluidStack stack = tank.getFluid(); + if (stack == null || stack.amount == 0 || !ConfigHolder.client.enableFancyChestRender) + return; + if (world != null) { renderState.setBrightness(world, pos); } - FluidStack stack = tank.getFluid(); - if (stack == null || stack.amount == 0) - return; Cuboid6 partialFluidBox = new Cuboid6(1.0625 / 16.0, 2.0625 / 16.0, 1.0625 / 16.0, 14.9375 / 16.0, 14.9375 / 16.0, 14.9375 / 16.0); double fillFraction = (double) stack.amount / tank.getCapacity(); - if (tank.getFluid().getFluid().isGaseous()) { + boolean gas = stack.getFluid().isGaseous(); + if (gas) { partialFluidBox.min.y = Math.max(13.9375 - (11.875 * fillFraction), 2.0) / 16.0; } else { partialFluidBox.max.y = Math.min((11.875 * fillFraction) + 2.0625, 14.0) / 16.0; @@ -133,15 +161,34 @@ public static void renderTankFluid(CCRenderState renderState, Matrix4 translatio ResourceLocation fluidStill = stack.getFluid().getStill(stack); TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks() .getAtlasSprite(fluidStill.toString()); - for (EnumFacing facing : EnumFacing.VALUES) { - Textures.renderFace(renderState, translation, pipeline, facing, partialFluidBox, fluidStillSprite, - BlockRenderLayer.CUTOUT_MIPPED); - } + + Textures.renderFace(renderState, translation, pipeline, frontFacing, partialFluidBox, fluidStillSprite, + BlockRenderLayer.CUTOUT_MIPPED); + + Textures.renderFace(renderState, translation, pipeline, gas ? EnumFacing.DOWN : EnumFacing.UP, partialFluidBox, + fluidStillSprite, + BlockRenderLayer.CUTOUT_MIPPED); + GlStateManager.resetColor(); renderState.reset(); } + /** + * Takes in the difference in x, y, and z from the camera to the rendering TE and + * calculates the squared distance and checks if it's within the range squared + * + * @param x the difference in x from entity to this rendering TE + * @param y the difference in y from entity to this rendering TE + * @param z the difference in z from entity to this rendering TE + * @param range distance needed to be rendered + * @return true if the camera is within the given range, otherwise false + */ + public static boolean canRender(double x, double y, double z, double range) { + double distance = (x * x) + (y * y) + (z * z); + return distance < range * range; + } + public static void renderTankAmount(double x, double y, double z, EnumFacing frontFacing, long amount) { float lastBrightnessX = OpenGlHelper.lastBrightnessX; float lastBrightnessY = OpenGlHelper.lastBrightnessY; @@ -153,6 +200,9 @@ public static void renderTankAmount(double x, double y, double z, EnumFacing fro } public static void renderAmountText(double x, double y, double z, long amount, EnumFacing frontFacing) { + if (!ConfigHolder.client.enableFancyChestRender || !canRender(x, y, z, 64)) + return; + GlStateManager.pushMatrix(); GlStateManager.translate(x, y, z); GlStateManager.translate(frontFacing.getXOffset() * -1 / 16f, frontFacing.getYOffset() * -1 / 16f, @@ -167,7 +217,8 @@ public static void renderAmountText(double x, double y, double z, long amount, E GlStateManager.scale(1f / 64, 1f / 64, 0); GlStateManager.translate(-32, -32, 0); GlStateManager.disableLighting(); - new TextTexture(amountText, 0xFFFFFF).draw(0, 24, 64, 28); + textRenderer.setText(amountText); + textRenderer.draw(0, 24, 64, 28); GlStateManager.enableLighting(); GlStateManager.popMatrix(); } diff --git a/src/main/java/gregtech/common/ConfigHolder.java b/src/main/java/gregtech/common/ConfigHolder.java index 290fb9f7d64..caf04defc48 100644 --- a/src/main/java/gregtech/common/ConfigHolder.java +++ b/src/main/java/gregtech/common/ConfigHolder.java @@ -404,7 +404,7 @@ public static class ClientOptions { @Config.Comment({ "Whether or not to enable Emissive Textures for Electric Blast Furnace Coils when the multiblock is working.", - "Default: false" }) + "Default: true" }) public boolean coilsActiveEmissiveTextures = true; @Config.Comment({ "Whether or not sounds should be played when using tools outside of crafting.", @@ -456,6 +456,10 @@ public static class ClientOptions { @Config.Comment({ "Prevent optical and laser cables from animating when active.", "Default: false" }) public boolean preventAnimatedCables = false; + @Config.Comment({ "Enable the fancy rendering for Super/Quantum Chests/Tanks.", + "Default: true" }) + public boolean enableFancyChestRender = true; + public static class GuiConfig { @Config.Comment({ "The scrolling speed of widgets", "Default: 13" }) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java index 50dd8dc5cbe..e34f104d679 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java @@ -69,7 +69,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.getTier()); + this); Textures.CREATIVE_CONTAINER_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); Textures.PIPE_OUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); Textures.ITEM_OUTPUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java index 1f35630af35..3e93c1bcbd5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java @@ -52,7 +52,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.getTier()); + this); Textures.CREATIVE_CONTAINER_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (this.getOutputFacing() != null) { Textures.PIPE_OUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java index be6c63f5dec..bd6dca83fb8 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java @@ -102,7 +102,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.tier); + this); Textures.QUANTUM_CHEST_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (outputFacing != null) { Textures.PIPE_OUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java index d6624d95823..7e5d244f556 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java @@ -40,6 +40,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; @@ -134,9 +135,17 @@ public void update() { updatePreviousFluid(null); } else if (previousFluid.getFluid().equals(currentFluid.getFluid()) && previousFluid.amount != currentFluid.amount) { + int currentFill = MathHelper + .floor(16 * ((float) currentFluid.amount) / fluidTank.getCapacity()); + int previousFill = MathHelper + .floor(16 * ((float) previousFluid.amount) / fluidTank.getCapacity()); // tank has fluid with changed amount previousFluid.amount = currentFluid.amount; - writeCustomData(UPDATE_FLUID_AMOUNT, buf -> buf.writeInt(currentFluid.amount)); + writeCustomData(UPDATE_FLUID_AMOUNT, buf -> { + buf.writeInt(currentFluid.amount); + buf.writeBoolean(currentFill != previousFill); + }); + } else if (!previousFluid.equals(currentFluid)) { // tank has a different fluid from before @@ -266,7 +275,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.tier); + this); Textures.QUANTUM_TANK_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (outputFacing != null) { Textures.PIPE_OUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); @@ -282,6 +291,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, public void renderMetaTileEntity(double x, double y, double z, float partialTicks) { if (this.fluidTank.getFluid() == null || this.fluidTank.getFluid().amount == 0) return; + QuantumStorageRenderer.renderTankAmount(x, y, z, this.getFrontFacing(), this.fluidTank.getFluid().amount); } @@ -457,10 +467,12 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { } else if (dataId == UPDATE_FLUID_AMOUNT) { // amount must always be read even if it cannot be used to ensure the reader index advances int amount = buf.readInt(); + boolean updateRendering = buf.readBoolean(); FluidStack stack = fluidTank.getFluid(); if (stack != null) { stack.amount = Math.min(amount, fluidTank.getCapacity()); - scheduleRenderUpdate(); + if (updateRendering) + scheduleRenderUpdate(); } } else if (dataId == UPDATE_IS_VOIDING) { setVoiding(buf.readBoolean()); From 3fdf8b8fb74a20a62f2b38447e70fce56d094e54 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Thu, 4 Apr 2024 16:07:25 -0700 Subject: [PATCH 111/168] Allow ITNT and PowderBarrels to make AE singularities (#2442) (cherry picked from commit 7e01d339fb2370eef00ad86b252a3dd00473a338) --- src/main/java/gregtech/common/EventHandlers.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/EventHandlers.java b/src/main/java/gregtech/common/EventHandlers.java index 588909961e5..8fa23091b99 100644 --- a/src/main/java/gregtech/common/EventHandlers.java +++ b/src/main/java/gregtech/common/EventHandlers.java @@ -12,6 +12,7 @@ import gregtech.api.util.BlockUtility; import gregtech.api.util.CapesRegistry; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.VirtualTankRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData; import gregtech.common.entities.EntityGTExplosive; @@ -23,6 +24,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityOtherPlayerMP; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; @@ -63,6 +65,8 @@ import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.ItemHandlerHelper; +import appeng.entity.EntitySingularity; + @Mod.EventBusSubscriber(modid = GTValues.MODID) public class EventHandlers { @@ -381,8 +385,12 @@ public static void onFurnaceFuelBurnTime(FurnaceFuelBurnTimeEvent event) { public static void onExplosionDetonate(ExplosionEvent.Detonate event) { if (event.getExplosion().exploder instanceof EntityGTExplosive explosive) { if (explosive.dropsAllBlocks()) { - event.getAffectedEntities().removeIf(entity -> entity instanceof EntityItem); + event.getAffectedEntities().removeIf(entity -> entity instanceof EntityItem && !checkAEEntity(entity)); } } } + + private static boolean checkAEEntity(Entity entity) { + return Mods.AppliedEnergistics2.isModLoaded() && entity instanceof EntitySingularity; + } } From e4aa94db269b5e2f6a2f5db060b66656d9d31229 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Thu, 4 Apr 2024 19:17:36 -0400 Subject: [PATCH 112/168] adjust recipe input expected cache size dynamically (#2331) (cherry picked from commit 251a9ac7306f76205d3505c8febea18066ce5a15) --- src/main/java/gregtech/GregTechMod.java | 2 + .../api/persistence/PersistentData.java | 108 +++++++++++++++ .../api/recipes/GTRecipeInputCache.java | 124 ++++++++++++++---- 3 files changed, 210 insertions(+), 24 deletions(-) create mode 100644 src/main/java/gregtech/api/persistence/PersistentData.java diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 3d9cbeabd6c..791e8944281 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.modules.ModuleContainerRegistryEvent; +import gregtech.api.persistence.PersistentData; import gregtech.client.utils.BloomEffectUtil; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; @@ -49,6 +50,7 @@ public GregTechMod() { @EventHandler public void onConstruction(FMLConstructionEvent event) { + PersistentData.instance().init(); moduleManager = ModuleManager.getInstance(); GregTechAPI.moduleManager = moduleManager; moduleManager.registerContainer(new GregTechModules()); diff --git a/src/main/java/gregtech/api/persistence/PersistentData.java b/src/main/java/gregtech/api/persistence/PersistentData.java new file mode 100644 index 00000000000..dc88872d9a3 --- /dev/null +++ b/src/main/java/gregtech/api/persistence/PersistentData.java @@ -0,0 +1,108 @@ +package gregtech.api.persistence; + +import gregtech.api.GTValues; +import gregtech.api.util.GTLog; + +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.common.Loader; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +public final class PersistentData { + + private static final PersistentData INSTANCE = new PersistentData(); + + private @Nullable Path path; + private @Nullable NBTTagCompound tag; + + public static @NotNull PersistentData instance() { + return INSTANCE; + } + + private PersistentData() {} + + @ApiStatus.Internal + public void init() { + this.path = Loader.instance().getConfigDir().toPath() + .resolve(GTValues.MODID) + .resolve("persistent_data.dat"); + } + + /** + * @return the stored persistent data + */ + public synchronized @NotNull NBTTagCompound getTag() { + if (this.tag == null) { + this.tag = read(); + } + return this.tag; + } + + /** + * @return the read NBTTagCompound from disk + */ + private @NotNull NBTTagCompound read() { + GTLog.logger.debug("Reading persistent data from path {}", path); + if (this.path == null) { + throw new IllegalStateException("Persistent data path cannot be null"); + } + + if (!Files.exists(path)) { + return new NBTTagCompound(); + } + + try (InputStream inputStream = Files.newInputStream(this.path)) { + return CompressedStreamTools.readCompressed(inputStream); + } catch (IOException e) { + GTLog.logger.error("Failed to read persistent data", e); + return new NBTTagCompound(); + } + } + + /** + * Save the GT Persistent data to disk + */ + public synchronized void save() { + if (this.tag != null) { + write(this.tag); + } + } + + /** + * @param tagCompound the tag compound to save to disk + */ + private void write(@NotNull NBTTagCompound tagCompound) { + GTLog.logger.debug("Writing persistent data to path {}", path); + if (tagCompound.isEmpty()) { + return; + } + + if (this.path == null) { + throw new IllegalStateException("Persistent data path cannot be null"); + } + + if (!Files.exists(path)) { + try { + Files.createDirectories(path.getParent()); + } catch (IOException e) { + GTLog.logger.error("Could not create persistent data dir", e); + return; + } + } + + try (OutputStream outputStream = Files.newOutputStream(path)) { + CompressedStreamTools.writeCompressed(tagCompound, outputStream); + } catch (IOException e) { + GTLog.logger.error("Failed to write persistent data", e); + } + } +} diff --git a/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java b/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java index f72fb572f6e..4e9a68fdf03 100644 --- a/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java +++ b/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java @@ -1,11 +1,18 @@ package gregtech.api.recipes; import gregtech.api.GTValues; +import gregtech.api.persistence.PersistentData; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.util.GTLog; import gregtech.common.ConfigHolder; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.MathHelper; + +import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collections; @@ -14,54 +21,77 @@ /** * Cache of GTRecipeInput instances for deduplication. *

- * Each GTRecipeInput is cached by an internal hashtable, and any duplicative - * instances will be replaced by identical object previously created. + * Each GTRecipeInput is cached by an internal hashtable, and any duplicative instances will be replaced by identical + * object previously created. *

- * Caching and duplication is only available during recipe registration; once - * recipe registration is over, the cache will be discarded and no further entries - * will be put into cache. + * Caching and duplication is only available during recipe registration; once recipe registration is over, the cache + * will be discarded and no further entries will be put into cache. */ -public class GTRecipeInputCache { +public final class GTRecipeInputCache { + + private static final int MINIMUM_CACHE_SIZE = 1 << 13; + private static final int MAXIMUM_CACHE_SIZE = 1 << 30; + + private static ObjectOpenHashSet instances; - private static final int EXPECTED_CACHE_SIZE = 16384; - private static ObjectOpenHashSet INSTANCES; + private static final String DATA_NAME = "expectedIngredientInstances"; + + private GTRecipeInputCache() {} public static boolean isCacheEnabled() { - return INSTANCES != null; + return instances != null; } + @ApiStatus.Internal public static void enableCache() { if (!isCacheEnabled()) { - INSTANCES = new ObjectOpenHashSet<>(EXPECTED_CACHE_SIZE, 1); - if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) - GTLog.logger.info("GTRecipeInput cache enabled"); + int size = calculateOptimalExpectedSize(); + instances = new ObjectOpenHashSet<>(size); + + if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) { + GTLog.logger.info("GTRecipeInput cache enabled with expected size {}", size); + } } } + @ApiStatus.Internal public static void disableCache() { if (isCacheEnabled()) { - if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) - GTLog.logger.info("GTRecipeInput cache disabled; releasing {} unique instances", INSTANCES.size()); - INSTANCES = null; + int size = instances.size(); + if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) { + GTLog.logger.info("GTRecipeInput cache disabled; releasing {} unique instances", size); + } + instances = null; + + if (size >= MINIMUM_CACHE_SIZE && size < MAXIMUM_CACHE_SIZE) { + NBTTagCompound tagCompound = PersistentData.instance().getTag(); + if (getExpectedInstanceAmount(tagCompound) != size) { + tagCompound.setInteger(DATA_NAME, size); + PersistentData.instance().save(); + } + } } } + private static int getExpectedInstanceAmount(@NotNull NBTTagCompound tagCompound) { + return MathHelper.clamp(tagCompound.getInteger(DATA_NAME), MINIMUM_CACHE_SIZE, MAXIMUM_CACHE_SIZE); + } + /** - * Tries to deduplicate the instance with previously cached instances. - * If there is no identical GTRecipeInput present in cache, the - * {@code recipeInput} will be put into cache, marked as cached, and returned subsequently. + * Tries to deduplicate the instance with previously cached instances. If there is no identical GTRecipeInput + * present in cache, the {@code recipeInput} will be put into cache, marked as cached, and returned subsequently. *

* This operation returns {@code recipeInput} without doing anything if cache is disabled. * * @param recipeInput ingredient instance to be deduplicated - * @return Either previously cached instance, or {@code recipeInput} marked cached; - * or unmodified {@code recipeInput} instance if the cache is disabled + * @return Either previously cached instance, or {@code recipeInput} marked cached; or unmodified + * {@code recipeInput} instance if the cache is disabled */ public static GTRecipeInput deduplicate(GTRecipeInput recipeInput) { if (!isCacheEnabled() || recipeInput.isCached()) { return recipeInput; } - GTRecipeInput cached = INSTANCES.addOrGet(recipeInput); + GTRecipeInput cached = instances.addOrGet(recipeInput); if (cached == recipeInput) { // If recipeInput is cached just now... cached.setCached(); } @@ -69,9 +99,9 @@ public static GTRecipeInput deduplicate(GTRecipeInput recipeInput) { } /** - * Tries to deduplicate each instance in the list with previously cached instances. - * If there is no identical GTRecipeInput present in cache, the - * {@code recipeInput} will be put into cache, marked as cached, and returned subsequently. + * Tries to deduplicate each instance in the list with previously cached instances. If there is no identical + * GTRecipeInput present in cache, the {@code recipeInput} will be put into cache, marked as cached, and returned + * subsequently. *

* This operation returns {@code inputs} without doing anything if cache is disabled. * @@ -91,4 +121,50 @@ public static List deduplicateInputs(List inputs) } return list; } + + /** + * Calculates the optimal expected size for the input cache: + *

    + *
  1. Pick a Load Factor to test: i.e. {@code 0.75f} (default).
  2. + *
  3. Pick a Size to test: i.e. {@code 8192}.
  4. + *
  5. Internal array's size: next highest power of 2 for {@code size / loadFactor}, + * {@code nextHighestPowerOf2(8192 / 0.75) = 16384}.
  6. + *
  7. The maximum amount of stored values before a rehash is required {@code arraySize * loadFactor}, + * {@code 16384 * 0.75 = 12288}.
  8. + *
  9. Compare with the known amount of values stored: {@code 12288 >= 11774}.
  10. + *
  11. If larger or equal, the initial capacity and load factor will not induce a rehash/resize.
  12. + *
+ * + * @return the optimal expected input cache size + */ + private static int calculateOptimalExpectedSize() { + int min = Math.max(getExpectedInstanceAmount(PersistentData.instance().getTag()), MINIMUM_CACHE_SIZE); + for (int i = 13; i < 31; i++) { + int sizeToTest = 1 << i; + int arraySize = nextHighestPowerOf2((int) (sizeToTest / Hash.DEFAULT_LOAD_FACTOR)); + int maxStoredBeforeRehash = (int) (arraySize * Hash.DEFAULT_LOAD_FACTOR); + + if (maxStoredBeforeRehash >= min) { + return sizeToTest; + } + } + return MINIMUM_CACHE_SIZE; + } + + /** + * Algorithm source. + * + * @param x the number to use + * @return the next highest power of 2 relative to the number + */ + private static int nextHighestPowerOf2(int x) { + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return x; + } } From 567d70d22bf1f515f0078ac2bf990883b15853f0 Mon Sep 17 00:00:00 2001 From: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Thu, 4 Apr 2024 16:38:10 -0700 Subject: [PATCH 113/168] GroovyScript 1.0.0 (#2425) Co-authored-by: TechLord22 <37029404+TechLord22@users.noreply.github.com> (cherry picked from commit 16ed04a0d17f0341d85227e9e9f214ba9e02088f) --- dependencies.gradle | 4 +- src/main/java/gregtech/GregTechMod.java | 2 +- .../integration/groovy/GroovyExpansions.java | 27 ++ .../GroovyMaterialBuilderExpansion.java | 10 + .../groovy/GroovyScriptModule.java | 143 ++++--- .../integration/groovy/MaterialExpansion.java | 225 +++++++++++ .../groovy/MaterialPropertyExpansion.java | 355 ++++++++++++++++++ .../integration/groovy/PropertyContainer.java | 47 +++ .../groovy/VirtualizedRecipeMap.java | 2 +- 9 files changed, 761 insertions(+), 54 deletions(-) create mode 100644 src/main/java/gregtech/integration/groovy/MaterialExpansion.java create mode 100644 src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java create mode 100644 src/main/java/gregtech/integration/groovy/PropertyContainer.java diff --git a/dependencies.gradle b/dependencies.gradle index 445b5e3963b..4ab81db91bd 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -40,8 +40,8 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") - api("com.cleanroommc:modularui:2.4.1") { transitive = false } - api("com.cleanroommc:groovyscript:0.8.0") { transitive = false } + api("com.cleanroommc:modularui:2.4.3") { transitive = false } + api("com.cleanroommc:groovyscript:1.0.1") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 791e8944281..127d3107586 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -33,7 +33,7 @@ dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + "after:appliedenergistics2;" + "after:forestry;" + "after:extrabees;" + "after:extratrees;" + "after:genetics;" + "after:magicbees;" + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + - "after:groovyscript@[0.7.0,);" + "after:theoneprobe;" + "after:hwyla;") + "after:groovyscript@[1.0.1,);" + "after:theoneprobe;" + "after:hwyla;") public class GregTechMod { // Hold this so that we can reference non-interface methods without diff --git a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java index 8c23fdf270f..e24191091e8 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java +++ b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java @@ -1,8 +1,13 @@ package gregtech.integration.groovy; +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.attribute.FluidAttributes; import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.properties.ToolProperty; import net.minecraft.util.ResourceLocation; @@ -39,4 +44,26 @@ public static Material.Builder materialBuilder(MaterialEvent event, int id, Stri } return materialBuilder(event, id, new ResourceLocation(domain, path)); } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel); + } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event) { + return toolBuilder(event, 1.0F, 1.0F, 100, 2); + } + + public static FluidBuilder fluidBuilder(MaterialEvent event) { + return new FluidBuilder(); + } + + public static Element addElement(MaterialEvent event, long protons, long neutrons, long halfLifeSeconds, + String decayTo, String name, String symbol, boolean isIsotope) { + return Elements.add(protons, neutrons, halfLifeSeconds, decayTo, name, symbol, isIsotope); + } + + public static FluidBuilder acidic(FluidBuilder builder) { + return builder.attributes(FluidAttributes.ACID); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index f4e30273435..2b67fa26844 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -8,6 +8,7 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.ToolProperty; import gregtech.api.unification.stack.MaterialStack; import net.minecraft.util.ResourceLocation; @@ -115,4 +116,13 @@ public static Material.Builder components(Material.Builder builder, Object... ob } return builder.components(materialStacks.toArray(new MaterialStack[0])); } + + public static Material.Builder toolStats(Material.Builder builder, ToolProperty.Builder toolBuilder) { + return builder.toolStats(toolBuilder.build()); + } + + public static Material.Builder toolStats(Material.Builder builder, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return builder.toolStats(ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel).build()); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index 571261241b2..f7f7e45bb51 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -2,11 +2,14 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; +import gregtech.api.fluids.FluidBuilder; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.event.MaterialEvent; import gregtech.api.unification.material.event.PostMaterialEvent; @@ -20,8 +23,6 @@ import gregtech.common.pipelike.fluidpipe.BlockFluidPipe; import gregtech.common.pipelike.itempipe.BlockItemPipe; import gregtech.integration.IntegrationSubmodule; -import gregtech.integration.crafttweaker.material.MaterialExpansion; -import gregtech.integration.crafttweaker.material.MaterialPropertyExpansion; import gregtech.modules.GregTechModules; import net.minecraft.item.ItemStack; @@ -35,24 +36,25 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.GroovyPlugin; -import com.cleanroommc.groovyscript.api.IGameObjectHandler; +import com.cleanroommc.groovyscript.api.IGameObjectParser; +import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; -import com.cleanroommc.groovyscript.event.EventBusType; -import com.cleanroommc.groovyscript.event.GroovyEventManager; -import com.cleanroommc.groovyscript.gameobjects.GameObjectHandlerManager; +import com.cleanroommc.groovyscript.gameobjects.GameObjectHandler; import com.cleanroommc.groovyscript.helper.EnumHelper; -import com.cleanroommc.groovyscript.sandbox.LoadStage; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; -import groovy.lang.Closure; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.eclipse.lsp4j.CompletionItem; +import org.eclipse.lsp4j.CompletionItemKind; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Supplier; @@ -68,7 +70,7 @@ public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPlugin { private static GroovyContainer modSupportContainer; - private static final Map> metaItems = new Object2ObjectOpenHashMap<>(); + private static final Object2ObjectOpenHashMap> metaItems = new Object2ObjectOpenHashMap<>(); @NotNull @Override @@ -87,12 +89,20 @@ public static boolean isCurrentlyRunning() { } public static > T parseAndValidateEnumValue(Class clazz, String raw, String type) { + return parseAndValidateEnumValue(clazz, raw, type, false); + } + + @Contract("_,_,_,true -> !null") + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type, + boolean crash) { T t = EnumHelper.valueOfNullable(clazz, raw, false); if (t == null) { - GroovyLog.get().error("Can't find {} for {} in material builder. Valid values are {};", + String msg = GroovyLog.format("Can't find {} for {} in material builder. Valid values are {};", type, raw, Arrays.toString(clazz.getEnumConstants())); + if (crash) throw new NoSuchElementException(msg); + GroovyLog.get().error(msg); return null; } return t; @@ -216,57 +226,90 @@ public static void loadMetaItemBracketHandler() { return "GregTech"; } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override public @Nullable ModPropertyContainer createModPropertyContainer() { - return new ModPropertyContainer() { - - public void materialEvent(EventPriority priority, Closure eventListener) { - if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { - GroovyLog.get().error("GregTech's material event can only be used in pre init!"); - return; - } - GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, MaterialEvent.class, - eventListener); - } - - public void materialEvent(Closure eventListener) { - materialEvent(EventPriority.NORMAL, eventListener); - } - - public void lateMaterialEvent(EventPriority priority, Closure eventListener) { - if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { - GroovyLog.get().error("GregTech's material event can only be used in pre init!"); - return; - } - GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, PostMaterialEvent.class, - eventListener); - } - - public void lateMaterialEvent(Closure eventListener) { - materialEvent(EventPriority.NORMAL, eventListener); - } - }; + return new PropertyContainer(); } @Override public void onCompatLoaded(GroovyContainer groovyContainer) { - modSupportContainer = groovyContainer; - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "recipemap", - IGameObjectHandler.wrapStringGetter(RecipeMap::getByName)); - - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "material", - IGameObjectHandler.wrapStringGetter(GregTechAPI.materialManager::getMaterial)); - - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "oreprefix", - IGameObjectHandler.wrapStringGetter(OrePrefix::getPrefix)); - - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "metaitem", - IGameObjectHandler.wrapStringGetter(GroovyScriptModule::getMetaItem), ItemStack.EMPTY); + GroovyScriptModule.modSupportContainer = groovyContainer; + GameObjectHandler.builder("recipemap", RecipeMap.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(RecipeMap::getByName)) + .completerOfNamed(RecipeMap::getRecipeMaps, RecipeMap::getUnlocalizedName) + .register(); + GameObjectHandler.builder("material", Material.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) + .completerOfNamed(GregTechAPI.materialManager::getRegisteredMaterials, + mat -> mat.getResourceLocation().toString()) + .register(); + + GameObjectHandler.builder("oreprefix", OrePrefix.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(OrePrefix::getPrefix)) + .completerOfNamed(OrePrefix::values, v -> v.name) + .register(); + + GameObjectHandler.builder("metaitem", ItemStack.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) + .completer((paramIndex, items) -> { + if (paramIndex != 0) return; + for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) { + var entry = iterator.next(); + String mod = entry.getKey(); + for (String key : entry.getValue().keySet()) { + var item = new CompletionItem(mod + ":" + key); + item.setKind(CompletionItemKind.Constant); + items.add(item); + } + } + }) + .register(); + + GameObjectHandler.builder("element", Element.class) + .mod(GTValues.MODID) + .parser((s, args) -> { + Element element = Elements.get(s); + if (element != null) return Result.some(element); + if (s.length() <= 6) { + for (Element element1 : Elements.getAllElements()) { + if (element1.symbol.equals(s)) { + return Result.some(element1); + } + } + } + return Result.error(); + }) + .completerOfNamed(Elements::getAllElements, Element::getName) + .register(); ExpansionHelper.mixinClass(Material.class, MaterialExpansion.class); ExpansionHelper.mixinClass(Material.class, MaterialPropertyExpansion.class); ExpansionHelper.mixinClass(Material.Builder.class, GroovyMaterialBuilderExpansion.class); ExpansionHelper.mixinMethod(RecipeBuilder.class, GroovyExpansions.class, "property"); ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "materialBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(FluidBuilder.class, GroovyExpansions.class, "acidic"); + } + + protected static boolean checkFrozen(String description) { + if (!GregTechAPI.materialManager.canModifyMaterials()) { + GroovyLog.get().error("Cannot {} now, must be done in preInit loadStage and material event", description); + return true; + } + return false; + } + + protected static void logError(Material m, String cause, String type) { + GroovyLog.get().error( + "Cannot {0} of a Material with no {1}! Try calling \"add{1}\" in your late material event first if this is intentional. Material: {2}", + cause, type, m.getUnlocalizedName()); } } diff --git a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java new file mode 100644 index 00000000000..70b92dd04d9 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java @@ -0,0 +1,225 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.info.MaterialFlag; +import gregtech.api.unification.material.info.MaterialIconSet; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; + +import net.minecraft.enchantment.Enchantment; + +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; +import static gregtech.integration.groovy.GroovyScriptModule.logError; + +@SuppressWarnings("unused") +public class MaterialExpansion { + + //////////////////////////////////// + // Material Methods // + //////////////////////////////////// + + public static void setFormula(Material m, String formula) { + setFormula(m, formula, false); + } + + public static void setFormula(Material m, String formula, boolean withFormatting) { + if (checkFrozen("set material chemical formula")) return; + m.setFormula(formula, withFormatting); + } + + public static boolean hasFlag(Material m, String flagName) { + return m.hasFlag(MaterialFlag.getByName(flagName)); + } + + public static void setIconSet(Material m, String iconSetName) { + if (checkFrozen("set material icon set")) return; + m.setMaterialIconSet(MaterialIconSet.getByName(iconSetName)); + } + + public static String getIconSet(Material m) { + return m.getMaterialIconSet().getName(); + } + + //////////////////////////////////// + // Fluid Property // + //////////////////////////////////// + + public static boolean isGaseous(Material m) { + FluidProperty prop = m.getProperty(PropertyKey.FLUID); + return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + } + + /////////////////////////////////// + // Dust Property // + /////////////////////////////////// + + public static int harvestLevel(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getHarvestLevel(); + } else logError(m, "get the harvest level", "Dust"); + return 0; + } + + public static int burnTime(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getBurnTime(); + } else logError(m, "get the burn time", "Dust"); + return 0; + } + + public static void setHarvestLevel(Material m, int harvestLevel) { + if (checkFrozen("set harvest level")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setHarvestLevel(harvestLevel); + } else logError(m, "set the harvest level", "Dust"); + } + + public static void setBurnTime(Material m, int burnTime) { + if (checkFrozen("set burn time")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setBurnTime(burnTime); + } else logError(m, "set the burn time", "Dust"); + } + + /////////////////////////////////// + // Tool Property // + /////////////////////////////////// + public static float toolSpeed(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolSpeed(); + } else logError(m, "get the tool speed", "Tool"); + return 0; + } + + public static float attackDamage(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolAttackDamage(); + } else logError(m, "get the tool attack damage", "Tool"); + return 0; + } + + public static int toolDurability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolDurability(); + } else logError(m, "get the tool durability", "Tool"); + return 0; + } + + public static int toolHarvestLevel(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolHarvestLevel(); + } else logError(m, "get the tool harvest level", "Tool"); + return 0; + } + + public static int toolEnchantability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolEnchantability(); + } else logError(m, "get the tool enchantability", "Tool"); + return 0; + } + + public static void addToolEnchantment(Material m, Enchantment enchantment, int level) { + addScaledToolEnchantment(m, enchantment, level, 0); + } + + public static void addScaledToolEnchantment(Material m, Enchantment enchantment, int level, double levelGrowth) { + if (checkFrozen("add tool enchantment")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.addEnchantmentForTools(enchantment, level, levelGrowth); + } else logError(m, "change tool enchantments", "Tool"); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, toolHarvestLevel, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel, + boolean shouldIngoreCraftingTools) { + if (checkFrozen("set tool stats")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.setToolSpeed(toolSpeed); + prop.setToolAttackDamage(toolAttackDamage); + prop.setToolDurability(toolDurability); + prop.setToolHarvestLevel(toolHarvestLevel == 0 ? 2 : toolHarvestLevel); + prop.setToolEnchantability(enchantability == 0 ? 10 : enchantability); + prop.setShouldIgnoreCraftingTools(shouldIngoreCraftingTools); + } else logError(m, "change tool stats", "Tool"); + } + + // Wire/Item Pipe/Fluid Pipe stuff? + + //////////////////////////////////// + // Blast Property // + //////////////////////////////////// + + public static void setBlastTemp(Material m, int blastTemp) { + if (checkFrozen("set blast temperature")) return; + if (blastTemp <= 0) { + GroovyLog.get().error("Blast Temperature must be greater than zero! Material: " + m.getUnlocalizedName()); + return; + } + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) prop.setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static int blastTemp(Material m) { + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) { + return prop.getBlastTemperature(); + } else logError(m, "get blast temperature", "Blast"); + return 0; + } + + //////////////////////////////////// + // Ore Property // + //////////////////////////////////// + + public static int oreMultiplier(Material m) { + OreProperty prop = m.getProperty(PropertyKey.ORE); + if (prop != null) { + return prop.getOreMultiplier(); + } else logError(m, "get ore multiplier", "Ore"); + return 0; + } +} diff --git a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java new file mode 100644 index 00000000000..83ceb1b27a7 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java @@ -0,0 +1,355 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.FluidState; +import gregtech.api.fluids.attribute.FluidAttributes; +import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidPipeProperties; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.GemProperty; +import gregtech.api.unification.material.properties.IngotProperty; +import gregtech.api.unification.material.properties.ItemPipeProperties; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.material.properties.WireProperties; +import gregtech.api.unification.material.properties.WoodProperty; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; + +@SuppressWarnings("unused") +public class MaterialPropertyExpansion { + + ///////////////////////////////////// + // Property Checkers // + ///////////////////////////////////// + + public static boolean hasBlastTemp(Material m) { + return m.hasProperty(PropertyKey.BLAST); + } + + public static boolean hasDust(Material m) { + return m.hasProperty(PropertyKey.DUST); + } + + public static boolean hasFluidPipes(Material m) { + return m.hasProperty(PropertyKey.FLUID_PIPE); + } + + public static boolean hasFluid(Material m) { + return m.hasProperty(PropertyKey.FLUID); + } + + public static boolean hasGem(Material m) { + return m.hasProperty(PropertyKey.GEM); + } + + public static boolean hasIngot(Material m) { + return m.hasProperty(PropertyKey.INGOT); + } + + public static boolean hasItemPipes(Material m) { + return m.hasProperty(PropertyKey.ITEM_PIPE); + } + + public static boolean hasOre(Material m) { + return m.hasProperty(PropertyKey.ORE); + } + + public static boolean hasTools(Material m) { + return m.hasProperty(PropertyKey.TOOL); + } + + public static boolean hasWires(Material m) { + return m.hasProperty(PropertyKey.WIRE); + } + + //////////////////////////////////// + // Property Setters // + //////////////////////////////////// + + public static void addBlastTemp(Material m, int blastTemp) { + if (checkFrozen("add blast temperature")) return; + if (m.hasProperty(PropertyKey.BLAST)) m.getProperty(PropertyKey.BLAST).setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static void addBlastProperty(Material m, int blastTemp) { + addBlastProperty(m, blastTemp, null, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier) { + addBlastProperty(m, blastTemp, gasTier, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, eutOverride, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride, + int vacuumDurationOverride, int vacuumEUtOverride) { + if (checkFrozen("add blast property")) return; + if (m.hasProperty(PropertyKey.BLAST)) { + BlastProperty property = m.getProperty(PropertyKey.BLAST); + property.setBlastTemperature(blastTemp); + if (gasTier != null) property.setGasTier(BlastProperty.validateGasTier(gasTier)); + if (durationOverride != 0) property.setDurationOverride(durationOverride); + if (eutOverride != 0) property.setEutOverride(eutOverride); + if (vacuumDurationOverride != 0) property.setVacuumDurationOverride(vacuumDurationOverride); + if (vacuumEUtOverride != 0) property.setVacuumEutOverride(vacuumEUtOverride); + } else { + BlastProperty.Builder builder = new BlastProperty.Builder(); + builder.temp(blastTemp, + gasTier == null ? BlastProperty.GasTier.LOW : BlastProperty.validateGasTier(gasTier)); + builder.blastStats(durationOverride == 0 ? -1 : durationOverride, eutOverride == 0 ? -1 : eutOverride); + builder.vacuumStats(vacuumEUtOverride == 0 ? -1 : vacuumEUtOverride, + vacuumDurationOverride == 0 ? -1 : vacuumDurationOverride); + m.setProperty(PropertyKey.BLAST, builder.build()); + } + } + + public static void addDust(Material m) { + addDust(m, 0, 0); + } + + public static void addDust(Material m, int harvestLevel) { + addDust(m, harvestLevel, 0); + } + + public static void addDust(Material m, int harvestLevel, int burnTime) { + if (checkFrozen("add a dust to a material")) return; + if (harvestLevel == 0) harvestLevel = 2; + if (m.hasProperty(PropertyKey.DUST)) { + m.getProperty(PropertyKey.DUST).setHarvestLevel(harvestLevel); + m.getProperty(PropertyKey.DUST).setBurnTime(burnTime); + } else m.setProperty(PropertyKey.DUST, new DustProperty(harvestLevel, burnTime)); + } + + public static void addWood(Material m) { + if (checkFrozen("add a wood to a material")) return; + if (!m.hasProperty(PropertyKey.WOOD)) { + m.setProperty(PropertyKey.WOOD, new WoodProperty()); + } + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof) { + addFluidPipes(m, maxFluidTemperature, throughput, gasProof, false, false, false); + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof, + boolean acidProof, boolean cryoProof, boolean plasmaProof) { + if (checkFrozen("add fluid pipes to a material")) return; + if (m.hasProperty(PropertyKey.FLUID_PIPE)) { + m.getProperty(PropertyKey.FLUID_PIPE).setMaxFluidTemperature(maxFluidTemperature); + m.getProperty(PropertyKey.FLUID_PIPE).setThroughput(throughput); + m.getProperty(PropertyKey.FLUID_PIPE).setGasProof(gasProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCanContain(FluidAttributes.ACID, acidProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCryoProof(cryoProof); + m.getProperty(PropertyKey.FLUID_PIPE).setPlasmaProof(plasmaProof); + } else { + m.setProperty(PropertyKey.FLUID_PIPE, new FluidPipeProperties(maxFluidTemperature, throughput, gasProof, + acidProof, cryoProof, plasmaProof)); + } + } + + @GroovyBlacklist + private static void addFluidInternal(Material m, FluidStorageKey key, FluidBuilder builder) { + if (checkFrozen("add a Fluid to a material")) return; + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (property == null) { + property = new FluidProperty(); + m.setProperty(PropertyKey.FLUID, property); + } + property.getStorage().enqueueRegistration(key, builder); + } + + public static void addLiquid(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.LIQUID, builder.state(FluidState.LIQUID)); + } + + public static void addLiquid(Material m) { + addLiquid(m, new FluidBuilder()); + } + + public static void addFluid(Material m) { + addLiquid(m); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName) { + addFluid(m, fluidTypeName, false); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName, boolean hasBlock) { + GroovyLog.get().error("The usage of `material.addFluid(String, boolean)` is strongly discouraged. " + + "Please use `addLiquid()`, `addGas()` or `addPlasma()` with or without `FluidBuilder`."); + if (checkFrozen("add a Fluid to a material")) return; + FluidState type = GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type", + true); + FluidStorageKey storageKey = switch (type) { + case LIQUID -> FluidStorageKeys.LIQUID; + case GAS -> FluidStorageKeys.GAS; + case PLASMA -> FluidStorageKeys.PLASMA; + }; + FluidBuilder builder = new FluidBuilder(); + builder.state(type); + if (hasBlock) builder.block(); + addFluidInternal(m, storageKey, builder); + } + + public static void addGas(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.GAS, builder.state(FluidState.GAS)); + } + + public static void addGas(Material m) { + addGas(m, new FluidBuilder()); + } + + public static void addPlasma(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); + } + + public static void addPlasma(Material m) { + addPlasma(m, new FluidBuilder()); + } + + public static void addGem(Material m) { + if (checkFrozen("add a Gem to a material")) return; + if (!m.hasProperty(PropertyKey.GEM)) m.setProperty(PropertyKey.GEM, new GemProperty()); + } + + public static void addIngot(Material m) { + if (checkFrozen("add an Ingot to a material")) return; + if (!m.hasProperty(PropertyKey.INGOT)) m.setProperty(PropertyKey.INGOT, new IngotProperty()); + } + + public static void addOre(Material m) { + addOre(m, false); + } + + public static void addOre(Material m, boolean emissive) { + addOre(m, 0, 0, emissive); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier) { + addOre(m, oreMultiplier, byproductMultiplier, false); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier, boolean emissive) { + if (checkFrozen("add an Ore to a material")) return; + oreMultiplier = oreMultiplier == 0 ? 1 : oreMultiplier; + byproductMultiplier = byproductMultiplier == 0 ? 1 : byproductMultiplier; + if (m.hasProperty(PropertyKey.ORE)) { + m.getProperty(PropertyKey.ORE).setOreMultiplier(oreMultiplier); + m.getProperty(PropertyKey.ORE).setByProductMultiplier(byproductMultiplier); + m.getProperty(PropertyKey.ORE).setEmissive(emissive); + } else m.setProperty(PropertyKey.ORE, new OreProperty(oreMultiplier, byproductMultiplier, emissive)); + } + + public static void addItemPipes(Material m, int priority, float transferRate) { + if (checkFrozen("add Item Pipes to a material")) return; + if (m.hasProperty(PropertyKey.ITEM_PIPE)) { + m.getProperty(PropertyKey.ITEM_PIPE).setPriority(priority); + m.getProperty(PropertyKey.ITEM_PIPE).setTransferRate(transferRate); + } else m.setProperty(PropertyKey.ITEM_PIPE, new ItemPipeProperties(priority, transferRate)); + } + + public static void addTools(Material m, ToolProperty.Builder builder) { + addTools(m, builder.build()); + } + + public static void addTools(Material m, ToolProperty prop) { + if (checkFrozen("add Tools to a material")) return; + ToolProperty property = m.getProperty(PropertyKey.TOOL); + if (property != null) { + property.setToolSpeed(prop.getToolSpeed()); + property.setToolAttackDamage(prop.getToolAttackDamage()); + property.setToolDurability(prop.getToolDurability()); + property.setToolHarvestLevel(prop.getToolHarvestLevel()); + property.setToolAttackSpeed(prop.getToolAttackSpeed()); + property.setToolEnchantability(prop.getToolEnchantability()); + property.setMagnetic(prop.isMagnetic()); + property.setUnbreakable(prop.getUnbreakable()); + property.setShouldIgnoreCraftingTools(prop.getShouldIgnoreCraftingTools()); + property.setDurabilityMultiplier(prop.getDurabilityMultiplier()); + } else { + m.setProperty(PropertyKey.TOOL, prop); + } + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, 0, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, toolEnchantability, + 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability, + int durabilityMultiplier) { + if (toolEnchantability == 0) toolEnchantability = 10; + if (durabilityMultiplier <= 0) durabilityMultiplier = 1; + addTools(m, ToolProperty.Builder.of(toolSpeed, toolAttackDamage, toolDurability, toolHarvestLevel) + .attackSpeed(toolAttackSpeed) + .enchantability(toolEnchantability) + .durabilityMultiplier(durabilityMultiplier)); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + if (checkFrozen("add Wires to a material")) return; + if (m.hasProperty(PropertyKey.WIRE)) { + m.getProperty(PropertyKey.WIRE).setVoltage(voltage); + m.getProperty(PropertyKey.WIRE).setAmperage(baseAmperage); + m.getProperty(PropertyKey.WIRE).setLossPerBlock(lossPerBlock); + m.getProperty(PropertyKey.WIRE).setSuperconductor(isSuperCon); + m.getProperty(PropertyKey.WIRE).setSuperconductorCriticalTemperature(criticalTemp); + } else m.setProperty(PropertyKey.WIRE, + new WireProperties(voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp)); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp); + } +} diff --git a/src/main/java/gregtech/integration/groovy/PropertyContainer.java b/src/main/java/gregtech/integration/groovy/PropertyContainer.java new file mode 100644 index 00000000000..35da8ce4905 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/PropertyContainer.java @@ -0,0 +1,47 @@ +package gregtech.integration.groovy; + +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; + +import net.minecraftforge.fml.common.eventhandler.EventPriority; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.event.EventBusType; +import com.cleanroommc.groovyscript.event.GroovyEventManager; +import com.cleanroommc.groovyscript.sandbox.ClosureHelper; +import com.cleanroommc.groovyscript.sandbox.LoadStage; +import groovy.lang.Closure; +import groovy.lang.DelegatesTo; + +public class PropertyContainer extends ModPropertyContainer { + + public void materialEvent(EventPriority priority, @DelegatesTo(MaterialEvent.class) Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + ClosureHelper.withEnvironment(eventListener, new MaterialEvent(), true); + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, MaterialEvent.class, eventListener); + } + + public void materialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + + public void lateMaterialEvent(EventPriority priority, Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, PostMaterialEvent.class, + eventListener); + } + + public void lateMaterialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } +} diff --git a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java index a2dbf7a3d55..6bd80f4db05 100644 --- a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java +++ b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java @@ -23,7 +23,7 @@ public class VirtualizedRecipeMap extends VirtualizedRegistry { public VirtualizedRecipeMap(RecipeMap recipeMap) { super(Alias.generateOf(recipeMap.unlocalizedName, CaseFormat.LOWER_UNDERSCORE)); this.recipeMap = recipeMap; - GroovyScriptModule.getInstance().getVirtualizedRegistrar().addRegistry(this); + GroovyScriptModule.getInstance().getRegistrar().addRegistry(this); } @Override From e701f729b738ba4ed24d1274e45d71dc6f80a4bb Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 14 Apr 2024 13:31:48 -0400 Subject: [PATCH 114/168] fix primitive multiblocks allowing automation through their controller (#2452) (cherry picked from commit a8a0ddaa157c78ccba1d544d8789c7d0966b09a9) --- ...ecipeMapPrimitiveMultiblockController.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java index d5bd83b3413..da874e0bdb8 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java @@ -1,12 +1,21 @@ package gregtech.api.metatileentity.multiblock; -import gregtech.api.capability.impl.*; +import gregtech.api.capability.impl.FluidHandlerProxy; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerProxy; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.PrimitiveRecipeLogic; import gregtech.api.metatileentity.MTETrait; import gregtech.api.recipes.RecipeMap; +import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; +import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; import java.util.ArrayList; import java.util.List; @@ -44,6 +53,15 @@ private List makeFluidTanks(int length, boolean isExport) { return fluidTankList; } + @Override + public T getCapability(Capability capability, EnumFacing side) { + if ((capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || + capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && side != null) { + return null; + } + return super.getCapability(capability, side); + } + @Override protected void updateFormedValid() { recipeMapWorkable.update(); From 08fc0ee1fbd04f37454ab866e0e7ea379727029e Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 14 Apr 2024 13:41:40 -0400 Subject: [PATCH 115/168] Waila/Hwyla Provider Fixes (#2451) (cherry picked from commit e927e2d9d54377c96ad2533a9d10e19679abc672) --- src/main/java/gregtech/GregTechMod.java | 2 +- src/main/java/gregtech/api/GTValues.java | 5 +++++ src/main/java/gregtech/api/util/GTLog.java | 4 +++- .../java/gregtech/api/util/input/KeyBind.java | 5 +++-- .../forestry/bees/GTBeeDefinition.java | 9 +++++++-- .../integration/groovy/GroovyScriptModule.java | 2 +- .../hwyla/provider/BlockOreDataProvider.java | 7 +++++-- .../hwyla/provider/ControllableDataProvider.java | 2 +- .../hwyla/provider/ConverterDataProvider.java | 2 +- .../hwyla/provider/DiodeDataProvider.java | 2 +- .../provider/ElectricContainerDataProvider.java | 2 +- .../hwyla/provider/LampDataProvider.java | 2 +- .../hwyla/provider/MaintenanceDataProvider.java | 2 +- .../provider/MultiRecipeMapDataProvider.java | 2 +- .../hwyla/provider/MultiblockDataProvider.java | 2 +- .../hwyla/provider/PrimitivePumpDataProvider.java | 2 +- .../hwyla/provider/RecipeLogicDataProvider.java | 5 +++-- .../hwyla/provider/SteamBoilerDataProvider.java | 2 +- .../hwyla/provider/TransformerDataProvider.java | 2 +- .../hwyla/provider/WorkableDataProvider.java | 2 +- .../resources/assets/gregtech/lang/en_us.lang | 15 +++++++++++++++ 21 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 127d3107586..5116e9b1018 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -27,7 +27,7 @@ import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; @Mod(modid = GTValues.MODID, - name = "GregTech", + name = GTValues.MOD_NAME, acceptedMinecraftVersions = "[1.12.2,1.13)", version = GTInternalTags.VERSION, dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 05053d6fbb8..006f9444117 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -126,6 +126,11 @@ public class GTValues { */ public static final String MODID = "gregtech"; + /** + * GregTech Mod Name + */ + public static final String MOD_NAME = "GregTech"; + /** @deprecated Use {@link gregtech.api.util.Mods} instead */ @Deprecated @ApiStatus.ScheduledForRemoval(inVersion = "2.9") diff --git a/src/main/java/gregtech/api/util/GTLog.java b/src/main/java/gregtech/api/util/GTLog.java index 56a003fde5b..a7e980f1e52 100644 --- a/src/main/java/gregtech/api/util/GTLog.java +++ b/src/main/java/gregtech/api/util/GTLog.java @@ -1,5 +1,7 @@ package gregtech.api.util; +import gregtech.api.GTValues; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -9,7 +11,7 @@ */ public class GTLog { - public static Logger logger = LogManager.getLogger("GregTech"); + public static Logger logger = LogManager.getLogger(GTValues.MOD_NAME); private GTLog() {} } diff --git a/src/main/java/gregtech/api/util/input/KeyBind.java b/src/main/java/gregtech/api/util/input/KeyBind.java index 309a4d28c1c..74ec9442afb 100644 --- a/src/main/java/gregtech/api/util/input/KeyBind.java +++ b/src/main/java/gregtech/api/util/input/KeyBind.java @@ -1,5 +1,6 @@ package gregtech.api.util.input; +import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.util.GTLog; import gregtech.core.network.packets.PacketKeysPressed; @@ -99,14 +100,14 @@ public static boolean scrollingDown() { KeyBind(String langKey, int button) { if (FMLCommonHandler.instance().getSide().isClient()) { - this.keybinding = new KeyBinding(langKey, button, "GregTech"); + this.keybinding = new KeyBinding(langKey, button, GTValues.MOD_NAME); ClientRegistry.registerKeyBinding(this.keybinding); } } KeyBind(String langKey, IKeyConflictContext ctx, int button) { if (FMLCommonHandler.instance().getSide().isClient()) { - this.keybinding = new KeyBinding(langKey, ctx, button, "GregTech"); + this.keybinding = new KeyBinding(langKey, ctx, button, GTValues.MOD_NAME); ClientRegistry.registerKeyBinding(this.keybinding); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index d4a967e4bfe..610c93e3d5f 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -18,7 +18,12 @@ import net.minecraftforge.fml.common.Optional; import appeng.core.Api; -import forestry.api.apiculture.*; +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeMutationBuilder; import forestry.api.core.EnumHumidity; import forestry.api.core.EnumTemperature; import forestry.api.genetics.IAllele; @@ -1206,7 +1211,7 @@ public enum GTBeeDefinition implements IBeeDefinition { String name = "for.bees.species." + lowercaseName; this.branch = branch; - this.species = new GTAlleleBeeSpecies(GTValues.MODID, uid, name, "GregTech", description, dominant, + this.species = new GTAlleleBeeSpecies(GTValues.MODID, uid, name, GTValues.MOD_NAME, description, dominant, branch.getBranch(), binomial, primary, secondary); this.generationCondition = generationCondition; } diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index f7f7e45bb51..62891a1f132 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -223,7 +223,7 @@ public static void loadMetaItemBracketHandler() { @Override public @NotNull String getContainerName() { - return "GregTech"; + return GTValues.MOD_NAME; } @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) diff --git a/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java index b8d6512742b..98654be839f 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java @@ -8,7 +8,10 @@ import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import mcp.mobius.waila.api.*; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; +import mcp.mobius.waila.api.IWailaDataProvider; +import mcp.mobius.waila.api.IWailaRegistrar; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -19,7 +22,7 @@ public class BlockOreDataProvider implements IWailaDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, BlockOre.class); - registrar.addConfig(GTValues.MODID, "gregtech.block_ore"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.block_ore"); } @NotNull diff --git a/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java index 20791ab3e34..84d8151c6bd 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java @@ -26,7 +26,7 @@ public class ControllableDataProvider extends CapabilityDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, TileEntity.class); registrar.registerNBTProvider(this, TileEntity.class); - registrar.addConfig(GTValues.MODID, "gregtech.workable"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.workable"); } @Override diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 17ecb6241af..413e8033fbe 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -104,6 +104,21 @@ gregtech.top.ld_pipe_output=Output gregtech.top.ld_pipe_input_endpoint=Input Endpoint: gregtech.top.ld_pipe_output_endpoint=Output Endpoint: +option.gregtech.block_ore=Ore Blocks +option.gregtech.controllable=Controllable Machines +option.gregtech.converter=Energy Converters +option.gregtech.diode=Diodes +option.gregtech.energy=Energy Containers +option.gregtech.block_lamp=Lamp Blocks +option.gregtech.maintenance=Maintenance Problems +option.gregtech.multi_recipemap=Machine Modes +option.gregtech.multiblock=Multiblocks +option.gregtech.primitive_pump=Primitive Pump +option.gregtech.recipe_logic=Recipes +option.gregtech.steam_boiler=Steam Boilers +option.gregtech.transformer=Transformers +option.gregtech.workable=Workable Machines + gregtech.waila.energy_stored=Energy: %d EU / %d EU gregtech.waila.progress_idle=Idle gregtech.waila.progress_tick=Progress: %d t / %d t From 92fba0219cdbb9098aad84ad11b77f3e9facc5b2 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Sun, 14 Apr 2024 13:09:16 -0500 Subject: [PATCH 116/168] Fix blocks not being able to choose preferred meta values in previews (#2446) (cherry picked from commit 40b2002c0a20e917be8e0fc4870e65670d064749) --- .../jei/multiblock/MultiblockInfoRecipeWrapper.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java index d0074db661c..b746f67a2cd 100644 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java @@ -527,7 +527,12 @@ private static Collection gatherStructureBlocks(World world, @NotNull stack = ((IGregTechTileEntity) tileEntity).getMetaTileEntity().getStackForm(); } if (stack.isEmpty()) { - // try the itemstack constructor if we're not a GT machine + // first, see what the block has to say for itself before forcing it to use a particular meta value + stack = block.getPickBlock(state, new RayTraceResult(Vec3d.ZERO, EnumFacing.UP, pos), world, pos, + new GregFakePlayer(world)); + } + if (stack.isEmpty()) { + // try the default itemstack constructor if we're not a GT machine stack = GTUtility.toItem(state); } if (stack.isEmpty()) { @@ -541,11 +546,6 @@ private static Collection gatherStructureBlocks(World world, @NotNull } } } - if (stack.isEmpty()) { - // if everything else doesn't work, try the not great getPickBlock() with some dummy values - stack = block.getPickBlock(state, new RayTraceResult(Vec3d.ZERO, EnumFacing.UP, pos), world, pos, - new GregFakePlayer(world)); - } // if we got a stack, add it to the set and map if (!stack.isEmpty()) { From 2935824885d94aeafb71c8bd035a37cee6d42f21 Mon Sep 17 00:00:00 2001 From: froot <66188216+kumquat-ir@users.noreply.github.com> Date: Sun, 14 Apr 2024 11:12:29 -0700 Subject: [PATCH 117/168] Fix display of sifter byproducts for materials with no exquisite (#2444) (cherry picked from commit e9b942561e3b4aeee4cf0850352928cd382308c7) --- .../integration/jei/basic/OreByProduct.java | 57 +++++++++---------- .../jei/basic/OreByProductCategory.java | 6 +- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/main/java/gregtech/integration/jei/basic/OreByProduct.java b/src/main/java/gregtech/integration/jei/basic/OreByProduct.java index fb1af11438b..8e062d069c0 100755 --- a/src/main/java/gregtech/integration/jei/basic/OreByProduct.java +++ b/src/main/java/gregtech/integration/jei/basic/OreByProduct.java @@ -1,6 +1,5 @@ package gregtech.integration.jei.basic; -import gregtech.api.GTValues; import gregtech.api.recipes.chance.output.impl.ChancedItemOutput; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; @@ -30,10 +29,14 @@ import java.util.ArrayList; import java.util.List; +import static gregtech.api.GTValues.LV; + public class OreByProduct implements IRecipeWrapper { private static final List ORES = new ArrayList<>(); + private static final int NUM_INPUTS = 21; + public static void addOreByProductPrefix(OrePrefix orePrefix) { if (!ORES.contains(orePrefix)) { ORES.add(orePrefix); @@ -62,14 +65,14 @@ public static void addOreByProductPrefix(OrePrefix orePrefix) { public OreByProduct(Material material) { if (ALWAYS_MACHINES == null) { ALWAYS_MACHINES = ImmutableList.of( - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.CENTRIFUGE[GTValues.LV].getStackForm(), - MetaTileEntities.ORE_WASHER[GTValues.LV].getStackForm(), - MetaTileEntities.THERMAL_CENTRIFUGE[GTValues.LV].getStackForm(), - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.CENTRIFUGE[GTValues.LV].getStackForm()); + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.CENTRIFUGE[LV].getStackForm(), + MetaTileEntities.ORE_WASHER[LV].getStackForm(), + MetaTileEntities.THERMAL_CENTRIFUGE[LV].getStackForm(), + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.CENTRIFUGE[LV].getStackForm()); } OreProperty property = material.getProperty(PropertyKey.ORE); int oreMultiplier = property.getOreMultiplier(); @@ -97,7 +100,7 @@ public OreByProduct(Material material) { // set up machines as inputs List simpleWashers = new ArrayList<>(); simpleWashers.add(new ItemStack(Items.CAULDRON)); - simpleWashers.add(MetaTileEntities.ORE_WASHER[GTValues.LV].getStackForm()); + simpleWashers.add(MetaTileEntities.ORE_WASHER[LV].getStackForm()); if (!material.hasProperty(PropertyKey.BLAST)) { addToInputs(new ItemStack(Blocks.FURNACE)); @@ -116,19 +119,19 @@ public OreByProduct(Material material) { if (washedIn != null && washedIn.getKey() != null) { hasChemBath = true; - addToInputs(MetaTileEntities.CHEMICAL_BATH[GTValues.LV].getStackForm()); + addToInputs(MetaTileEntities.CHEMICAL_BATH[LV].getStackForm()); } else { addToInputs(ItemStack.EMPTY); } if (separatedInto != null && !separatedInto.isEmpty()) { hasSeparator = true; - addToInputs(MetaTileEntities.ELECTROMAGNETIC_SEPARATOR[GTValues.LV].getStackForm()); + addToInputs(MetaTileEntities.ELECTROMAGNETIC_SEPARATOR[LV].getStackForm()); } else { addToInputs(ItemStack.EMPTY); } if (material.hasProperty(PropertyKey.GEM)) { hasSifter = true; - addToInputs(MetaTileEntities.SIFTER[GTValues.LV].getStackForm()); + addToInputs(MetaTileEntities.SIFTER[LV].getStackForm()); } else { addToInputs(ItemStack.EMPTY); } @@ -141,7 +144,7 @@ public OreByProduct(Material material) { } // total number of inputs added - currentSlot += 21; + currentSlot += NUM_INPUTS; // BASIC PROCESSING @@ -256,8 +259,6 @@ public OreByProduct(Material material) { // sifter if (hasSifter) { boolean highOutput = material.hasFlag(MaterialFlags.HIGH_SIFTER_OUTPUT); - ItemStack flawedStack = OreDictUnifier.get(OrePrefix.gemFlawed, material); - ItemStack chippedStack = OreDictUnifier.get(OrePrefix.gemChipped, material); addToOutputs(material, OrePrefix.gemExquisite, 1); addGemChance(300, 100, 500, 150, highOutput); @@ -267,19 +268,10 @@ public OreByProduct(Material material) { addGemChance(3500, 500, 5000, 1000, highOutput); addToOutputs(material, OrePrefix.dustPure, 1); addGemChance(5000, 750, 2500, 500, highOutput); - - if (!flawedStack.isEmpty()) { - addToOutputs(flawedStack); - addGemChance(2500, 300, 2000, 500, highOutput); - } else { - addEmptyOutputs(1); - } - if (!chippedStack.isEmpty()) { - addToOutputs(chippedStack); - addGemChance(3500, 400, 3000, 350, highOutput); - } else { - addEmptyOutputs(1); - } + addToOutputs(material, OrePrefix.gemFlawed, 1); + addGemChance(2500, 300, 2000, 500, highOutput); + addToOutputs(material, OrePrefix.gemChipped, 1); + addGemChance(3500, 400, 3000, 350, highOutput); } else { addEmptyOutputs(6); } @@ -345,8 +337,11 @@ private void addToInputs(ItemStack stack) { } private void addChance(int base, int tier) { - // this is solely for the chance overlay and tooltip, neither of which care about the ItemStack - chances.put(currentSlot - 1, new ChancedItemOutput(ItemStack.EMPTY, base, tier)); + // hacky check to not add a chance for empty stacks + if (!outputs.get(currentSlot - 1 - NUM_INPUTS).get(0).isEmpty()) { + // this is solely for the chance overlay and tooltip, neither of which care about the ItemStack + chances.put(currentSlot - 1, new ChancedItemOutput(ItemStack.EMPTY, base, tier)); + } } // make the code less :weary: diff --git a/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java b/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java index 635526f3114..db4f2bc6345 100644 --- a/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java +++ b/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java @@ -154,7 +154,7 @@ public void setRecipe(IRecipeLayout recipeLayout, @NotNull OreByProduct recipeWr new ItemStackTextRenderer(recipeWrapper.getChance(i / 2 + itemInputs.size()), ChancedOutputLogic.OR), ITEM_OUTPUT_LOCATIONS.get(i) + 1, ITEM_OUTPUT_LOCATIONS.get(i + 1) + 1, 16, 16, 0, 0); - itemOutputExists.add(itemOutputs.get(i / 2).size() > 0); + itemOutputExists.add(!itemOutputs.get(i / 2).isEmpty()); } List> fluidInputs = ingredients.getInputs(VanillaTypes.FLUID); @@ -162,7 +162,7 @@ public void setRecipe(IRecipeLayout recipeLayout, @NotNull OreByProduct recipeWr for (int i = 0; i < FLUID_LOCATIONS.size(); i += 2) { fluidStackGroup.init(i / 2, true, new FluidStackTextRenderer(1, false, 16, 16, null), FLUID_LOCATIONS.get(i) + 1, FLUID_LOCATIONS.get(i + 1) + 1, 16, 16, 0, 0); - fluidInputExists.add(fluidInputs.get(i / 2).size() > 0); + fluidInputExists.add(!fluidInputs.get(i / 2).isEmpty()); } itemStackGroup.addTooltipCallback(recipeWrapper::addTooltip); @@ -208,7 +208,7 @@ public void drawExtras(@NotNull Minecraft minecraft) { for (int i = 0; i < ITEM_OUTPUT_LOCATIONS.size(); i += 2) { // stupid hack to show all sifter slots if the first one exists - if (itemOutputExists.get(i / 2) || (i > 28 * 2 && itemOutputExists.get(28) && hasSifter)) { + if (itemOutputExists.get(i / 2) || (i >= 28 * 2 && hasSifter)) { slot.draw(minecraft, ITEM_OUTPUT_LOCATIONS.get(i), ITEM_OUTPUT_LOCATIONS.get(i + 1)); } } From 2f8d115b26fbbe9789f1f901e31cd3fed3e822b2 Mon Sep 17 00:00:00 2001 From: vrejhead <113960896+vrejhead@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:21:39 -0700 Subject: [PATCH 118/168] Fix possible NPE from MultiblockDisplayText (#2453) (cherry picked from commit 596a08b521d0a6a4fa3009665b065df434fefb81) --- .../api/metatileentity/multiblock/MultiblockDisplayText.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java index 0802125bf07..8cacd124e56 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java @@ -456,7 +456,7 @@ public Builder addMufflerObstructedLine(boolean isObstructed) { * Added if structure is formed, the machine is active, and the passed fuelName parameter is not null. */ public Builder addFuelNeededLine(String fuelName, int previousRecipeDuration) { - if (!isStructureFormed || !isActive) return this; + if (!isStructureFormed || !isActive || fuelName == null) return this; ITextComponent fuelNeeded = TextComponentUtil.stringWithColor(TextFormatting.RED, fuelName); ITextComponent numTicks = TextComponentUtil.stringWithColor(TextFormatting.AQUA, TextFormattingUtil.formatNumbers(previousRecipeDuration)); From 71405bed9683c7e2cd52e458f80528c7d84c6864 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:21:59 -0400 Subject: [PATCH 119/168] fix NPE with null fluids in quantum tanks (#2443) (cherry picked from commit 00032967afeaf39dab06d0a04efc4348b17c731b) --- .../texture/custom/QuantumStorageRenderer.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java index c5379c4e3af..03c0dd5656c 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java @@ -25,6 +25,7 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fml.relauncher.Side; @@ -139,8 +140,14 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity public static void renderTankFluid(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, FluidTank tank, IBlockAccess world, BlockPos pos, EnumFacing frontFacing) { FluidStack stack = tank.getFluid(); - if (stack == null || stack.amount == 0 || !ConfigHolder.client.enableFancyChestRender) + if (stack == null || stack.amount == 0 || !ConfigHolder.client.enableFancyChestRender) { return; + } + + Fluid fluid = stack.getFluid(); + if (fluid == null) { + return; + } if (world != null) { renderState.setBrightness(world, pos); @@ -150,7 +157,7 @@ public static void renderTankFluid(CCRenderState renderState, Matrix4 translatio 14.9375 / 16.0, 14.9375 / 16.0); double fillFraction = (double) stack.amount / tank.getCapacity(); - boolean gas = stack.getFluid().isGaseous(); + boolean gas = fluid.isGaseous(stack); if (gas) { partialFluidBox.min.y = Math.max(13.9375 - (11.875 * fillFraction), 2.0) / 16.0; } else { @@ -158,7 +165,7 @@ public static void renderTankFluid(CCRenderState renderState, Matrix4 translatio } renderState.setFluidColour(stack); - ResourceLocation fluidStill = stack.getFluid().getStill(stack); + ResourceLocation fluidStill = fluid.getStill(stack); TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks() .getAtlasSprite(fluidStill.toString()); From 47d818519319b026e4d335a4b21ff0482754e343 Mon Sep 17 00:00:00 2001 From: froot <66188216+kumquat-ir@users.noreply.github.com> Date: Sat, 4 May 2024 16:41:18 -0700 Subject: [PATCH 120/168] Remove NuclearCraft ASM (#2467) (cherry picked from commit 43b75c589f84388e70c66a59a879cecfa769be7c) --- .../gregtech/asm/GregTechTransformer.java | 16 ---------- .../NuclearCraftRecipeHelperVisitor.java | 29 ------------------- 2 files changed, 45 deletions(-) delete mode 100644 src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java diff --git a/src/main/java/gregtech/asm/GregTechTransformer.java b/src/main/java/gregtech/asm/GregTechTransformer.java index 005ec295075..4bdf742b499 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -1,6 +1,5 @@ package gregtech.asm; -import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import gregtech.asm.util.TargetClassVisitor; import gregtech.asm.visitors.*; @@ -130,21 +129,6 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) classReader.accept(new TargetClassVisitor(classWriter, CCLVisitor.TARGET_METHOD, CCLVisitor::new), 0); return classWriter.toByteArray(); } - case NuclearCraftRecipeHelperVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(0); - - // fix NC recipe compat different depending on overhaul vs normal - if (Mods.NuclearCraftOverhauled.isModLoaded()) { - classReader.accept(new TargetClassVisitor(classWriter, - NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NCO, NuclearCraftRecipeHelperVisitor::new), - 0); - } else if (Mods.NuclearCraft.isModLoaded()) { - classReader.accept(new TargetClassVisitor(classWriter, - NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NC, NuclearCraftRecipeHelperVisitor::new), 0); - } - return classWriter.toByteArray(); - } case RenderItemVisitor.TARGET_CLASS_NAME: { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); diff --git a/src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java b/src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java deleted file mode 100644 index a70986c67fb..00000000000 --- a/src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java +++ /dev/null @@ -1,29 +0,0 @@ -package gregtech.asm.visitors; - -import gregtech.asm.util.ObfMapping; - -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -public class NuclearCraftRecipeHelperVisitor extends MethodVisitor implements Opcodes { - - public static final String TARGET_CLASS_NAME = "nc/integration/gtce/GTCERecipeHelper"; - - public static final ObfMapping TARGET_METHOD_NC = new ObfMapping(TARGET_CLASS_NAME, "addGTCERecipe", - "(Ljava/lang/String;Lnc/recipe/ProcessorRecipe;)V"); - public static final ObfMapping TARGET_METHOD_NCO = new ObfMapping(TARGET_CLASS_NAME, "addGTCERecipe", - "(Ljava/lang/String;Lnc/recipe/BasicRecipe;)V"); - - public NuclearCraftRecipeHelperVisitor(MethodVisitor mv) { - super(ASM5, mv); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - if (opcode == GETSTATIC && name.equals("FLUID_EXTRACTION_RECIPES")) { // FLUID_EXTRACTION_RECIPES -> - // EXTRACTOR_RECIPES - name = "EXTRACTOR_RECIPES"; - } - super.visitFieldInsn(opcode, owner, name, desc); - } -} From 1c621939c06295112da7b3e1d7456566a2d8ad2a Mon Sep 17 00:00:00 2001 From: iouter <62897714+iouter@users.noreply.github.com> Date: Sun, 5 May 2024 08:42:47 +0800 Subject: [PATCH 121/168] Update zh_cn.lang (#2445) (cherry picked from commit f189493e0216ba80a20a34c23b08d3c26d8ccf7c) --- .../resources/assets/gregtech/lang/zh_cn.lang | 89 +++++++++++++------ 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index f47285403cf..adff7d709b4 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -47,7 +47,7 @@ gregtech.machine.steam_hatch.name=蒸汽仓 gregtech.machine.steam.steam_hatch.tooltip=§e可接受流体:§f蒸汽 gregtech.machine.steam_import_bus.name=输入总线(蒸汽) gregtech.machine.steam_export_bus.name=输出总线(蒸汽) -gregtech.machine.steam_bus.tooltip=无法作用于非蒸汽驱动的多方块机器 +gregtech.machine.steam_bus.tooltip=无法作用于非蒸汽驱动的多方块结构 gregtech.machine.steam_oven.name=蒸汽熔炼炉 gregtech.multiblock.steam_oven.description=蒸汽时代的多方块熔炉。需要至少6块青铜机械方块成型。仅可使用输入/输出总线(蒸汽),并且只能用蒸汽仓供给蒸汽。蒸汽仓必须放置于结构底层,数量至多为一个。 gregtech.multiblock.require_steam_parts=需要蒸汽仓与输入/输出总线(蒸汽)! @@ -104,6 +104,21 @@ gregtech.top.ld_pipe_output=输出 gregtech.top.ld_pipe_input_endpoint=输入接口: gregtech.top.ld_pipe_output_endpoint=输出接口: +option.gregtech.block_ore=矿石 +option.gregtech.controllable=机器控制器 +option.gregtech.converter=能量转换器 +option.gregtech.diode=二极管 +option.gregtech.energy=能量容器 +option.gregtech.block_lamp=灯方块 +option.gregtech.maintenance=维护问题 +option.gregtech.multi_recipemap=机器模式 +option.gregtech.multiblock=多方块结构 +option.gregtech.primitive_pump=原始水泵 +option.gregtech.recipe_logic=配方 +option.gregtech.steam_boiler=蒸汽锅炉 +option.gregtech.transformer=变压器 +option.gregtech.workable=机器工作状态 + gregtech.waila.energy_stored=能量:%d EU / %d EU gregtech.waila.progress_idle=闲置 gregtech.waila.progress_tick=进度:%d t / %d t @@ -124,17 +139,17 @@ gregtech.multiblock.electric_blast_furnace.description=电力高炉(EBF)是 gregtech.multiblock.multi_furnace.description=工业熔炉是种用于一次性烧制大量物品的多方块结构。不同级别的线圈会提供速度增幅和能量效率增幅。每次运作的基础烧制数量为32,且可以使用高等级的线圈增加烧制数量。 gregtech.multiblock.large_boiler.description=大型锅炉是种使用水和能量源产生蒸汽的多方块结构。这里说的“能量源”通常是指固体燃料和高密度流体。不同等级的锅炉仅在蒸汽产量上有所差别。 gregtech.multiblock.large_turbine.description=大型涡轮是种使用蒸汽、燃气或等离子体转动涡轮转子来发电的多方块结构。转子效率和转子转速会影响能量的输出。 -gregtech.multiblock.assembly_line.description=装配线是台由5到16“片”相同的结构所组成的大型多方块机器。理论上讲,它就是个大号组装机,用以生产高级合成组件。 -gregtech.multiblock.fusion_reactor.luv.description=核聚变反应堆MK-I是台大型多方块机器,用于融合元素形成更重的元素。它仅可使用LuV,ZPM或UV等级的能源仓。每个能源仓可增加10MEU的能量缓存,最大能量缓存为160MEU。 -gregtech.multiblock.fusion_reactor.zpm.description=核聚变反应堆MK-II是台大型多方块机器,用于融合元素形成更重的元素。它仅可使用ZPM或UV等级的能源仓。每个能源仓可增加20MEU的能量缓存,最大能量缓存为320MEU。 -gregtech.multiblock.fusion_reactor.uv.description=核聚变反应堆MK-III是台大型多方块机器,用于融合元素形成更重的元素。它仅可使用UV等级的能源仓。每个能源仓可增加40MEU的能量缓存,最大能量缓存为640MEU。 +gregtech.multiblock.assembly_line.description=装配线是台由5到16“片”相同的结构所组成的大型多方块结构。理论上讲,它就是个大号组装机,用以生产高级合成组件。 +gregtech.multiblock.fusion_reactor.luv.description=核聚变反应堆MK-I是台大型多方块结构,用于融合元素形成更重的元素。它仅可使用LuV,ZPM或UV等级的能源仓。每个能源仓可增加10MEU的能量缓存,最大能量缓存为160MEU。 +gregtech.multiblock.fusion_reactor.zpm.description=核聚变反应堆MK-II是台大型多方块结构,用于融合元素形成更重的元素。它仅可使用ZPM或UV等级的能源仓。每个能源仓可增加20MEU的能量缓存,最大能量缓存为320MEU。 +gregtech.multiblock.fusion_reactor.uv.description=核聚变反应堆MK-III是台大型多方块结构,用于融合元素形成更重的元素。它仅可使用UV等级的能源仓。每个能源仓可增加40MEU的能量缓存,最大能量缓存为640MEU。 gregtech.multiblock.fusion_reactor.heat=热量:%s -gregtech.multiblock.large_chemical_reactor.description=大型化学反应釜能够以100%的能效进行化学反应。每次超频将使处理速度与能耗均提升4倍。该多方块机器需要在中心位置的聚四氟乙烯管道外壳旁放置一个白铜线圈方块。 -gregtech.multiblock.primitive_water_pump.description=原始水泵是台前蒸汽时代的多方块机器。它每秒收集一次水资源,基础收集量取决于其所处的生物群系。水泵输出仓以及ULV和LV的输出仓都可以使用,输出仓的等级越高,水资源收集量也会越多。收集量的公式为:生物群系系数*输出仓倍数。 +gregtech.multiblock.large_chemical_reactor.description=大型化学反应釜能够以100%的能效进行化学反应。每次超频将使处理速度与能耗均提升4倍。该多方块结构需要在中心位置的聚四氟乙烯管道外壳旁放置一个白铜线圈方块。 +gregtech.multiblock.primitive_water_pump.description=原始水泵是台前蒸汽时代的多方块结构。它每秒收集一次水资源,基础收集量取决于其所处的生物群系。水泵输出仓以及ULV和LV的输出仓都可以使用,输出仓的等级越高,水资源收集量也会越多。收集量的公式为:生物群系系数*输出仓倍数。 gregtech.multiblock.primitive_water_pump.extra1=生物群系系数:/n 海洋(Ocean)、河流(River):1000 L/s/n 沼泽(Swamp):800 L/s/n 丛林(Jungle):350 L/s/n 积雪的(Snowy):300 L/s/n 平原(Plains)、森林(Forest):250 L/s/n 针叶林(Taiga):175 L/s/n 沙滩(Beach):170 L/s/n 其他:100 L/s gregtech.multiblock.primitive_water_pump.extra2=输出仓倍数:/n水泵输出仓:1x/nULV输出仓:2x/nLV输出仓:4x -gregtech.multiblock.processing_array.description=处理阵列可将最多16个单方块机器集成在一个多方块机器中,以实现更高效的自动化。 -gregtech.multiblock.advanced_processing_array.description=处理阵列可将最多64个单方块机器集成在一个多方块机器中,以实现更高效的自动化。 +gregtech.multiblock.processing_array.description=处理阵列可将最多16个单方块机器集成在一个多方块结构中,以实现更高效的自动化。 +gregtech.multiblock.advanced_processing_array.description=处理阵列可将最多64个单方块机器集成在一个多方块结构中,以实现更高效的自动化。 item.invalid.name=无效物品 fluid.empty=空 @@ -822,6 +837,7 @@ metaitem.fluid_filter.name=流体过滤卡 metaitem.fluid_filter.tooltip=作§f覆盖板§7时过滤§f流体§7的输入/输出。/n可用于升级§f电动泵§7与§f流体校准器§7。 metaitem.smart_item_filter.name=智能物品过滤卡 metaitem.smart_item_filter.tooltip=作§f覆盖板§7时以§f机器的配方§7过滤§f物品§7的输入/输出。/n亦可为§f运送模块§7和§f机械臂§7提供此种过滤功能。 +behaviour.filter_ui_manager=§f右键点击§7以配置,§fShift+右键§7清除配置 metaitem.cover.controller.name=机器控制覆盖板 metaitem.cover.controller.tooltip=作§f覆盖板§7时可以§f开/关§7机器。 @@ -1178,7 +1194,9 @@ cover.filter.blacklist.disabled=白名单 cover.filter.blacklist.enabled=黑名单 cover.ore_dictionary_filter.title=矿物词典过滤 -cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉 +cover.ore_dictionary_filter.info=§b接受复杂表达式\n§6a & b§r = 且\n§6a | b§r = 或\n§6a ^ b§r = 异或\n§6! abc§r = 非\n§6( abc )§r 表示组别\n§6*§r 表示通配(也即零或多个字符)\n§6?§r 表示任意一个字符\n§6()§r 匹配空条目(包括不带矿物词典的物品)\n§b使用范例:\n§6dust*Gold | (plate* & !*Double*)\n匹配双层板以外的板与包括小撮、小堆在内的所有金粉 +cover.ore_dictionary_filter.match_all=匹配所有:%s +cover.ore_dictionary_filter.case_sensitive=匹配大小写:%s cover.ore_dictionary_filter.test_slot.info=放入一件物品以测试是否匹配过滤表达式 cover.ore_dictionary_filter.test_slot.matches=§a* %s cover.ore_dictionary_filter.test_slot.matches_not=§c* %s @@ -1189,8 +1207,8 @@ cover.ore_dictionary_filter.status.err_warn=§c%s个错误、%s个警告 cover.ore_dictionary_filter.status.warn=§7%s个警告 cover.ore_dictionary_filter.status.no_issues=§a无问题 cover.ore_dictionary_filter.status.explain=矿物过滤说明: -cover.ore_dictionary_filter.button.case_sensitive.disabled=匹配大小写 -cover.ore_dictionary_filter.button.case_sensitive.enabled=忽略大小写 +cover.ore_dictionary_filter.button.case_sensitive.disabled=忽略大小写 +cover.ore_dictionary_filter.button.case_sensitive.enabled=匹配大小写 cover.ore_dictionary_filter.button.match_all.disabled=匹配物品的任一矿词条目 cover.ore_dictionary_filter.button.match_all.enabled=匹配物品的所有矿词条目 @@ -1243,6 +1261,7 @@ cover.fluid_filter.mode.filter_drain=过滤输出 cover.fluid_filter.mode.filter_both=过滤两者 cover.item_filter.title=物品过滤 +cover.filter.mode.title=过滤模式 cover.filter.mode.filter_insert=过滤输入 cover.filter.mode.filter_extract=过滤输出 cover.filter.mode.filter_both=过滤两者 @@ -1250,9 +1269,11 @@ cover.item_filter.ignore_damage.enabled=无视损坏值 cover.item_filter.ignore_damage.disabled=匹配损坏值 cover.item_filter.ignore_nbt.enabled=忽略NBT cover.item_filter.ignore_nbt.disabled=匹配NBT +cover.item_filter.config_amount=向上或向下滚动鼠标滚轮以增加或减少数量。\nShift[§6x4§r],Ctrl[§ex16§r],Shift+Ctrl[§ax64§r]\n亦可通过右击或左击来增减数量。\nShift+左键以清除 cover.voiding.voiding_mode.void_any=销毁匹配 cover.voiding.voiding_mode.void_overflow=销毁溢出 +cover.voiding.voiding_mode=销毁模式 cover.voiding.voiding_mode.description=§e销毁匹配§r:匹配过滤规则即销毁。/n§e溢出销毁§r:匹配过滤规则即销毁超出设定数量的部分物品/流体。 cover.fluid.voiding.title=流体销毁设置 cover.fluid.voiding.advanced.title=进阶流体销毁设置 @@ -1273,13 +1294,18 @@ cover.smart_item_filter.filtering_mode.centrifuge=离心机 cover.smart_item_filter.filtering_mode.sifter=筛选机 cover.smart_item_filter.filtering_mode.description=为该智能覆盖板选择目标机器。/n它能够自动传输符合机器配方的物品。 +cover.generic.transfer_mode=传输模式 +cover.generic.manual_io=特殊I/O模式 +cover.generic.io=I/O模式 +cover.pump.mode=泵模式 cover.conveyor.title=传送带覆盖板设置(%s) cover.conveyor.transfer_rate=§7件物品/秒 cover.conveyor.mode.export=模式:过滤输出 cover.conveyor.mode.import=模式:过滤输入 -cover.conveyor.distribution.round_robin_enhanced=分配模式/n§b增强轮询调度§r/n§7将物品平分至所有的物品存储空间 -cover.conveyor.distribution.round_robin=分配模式/n§b轮询调度§r(次序式)/n§7尝试将物品平分至物品存储空间 -cover.conveyor.distribution.first_insert=分配模式/n§b最近优先§r/n§7将物品输入至所搜寻到的首个物品存储空间 +cover.conveyor.distribution.name=分配模式 +cover.conveyor.distribution.round_robin_enhanced=§b增强轮询调度§r\n§7将物品平分至所有的物品存储空间 +cover.conveyor.distribution.round_robin=§b轮询调度§r(次序式)\n§7尝试将物品平分至物品存储空间 +cover.conveyor.distribution.first_insert=§b最近优先§r\n§7将物品输入至所搜寻到的首个物品存储空间 cover.conveyor.blocks_input.enabled=若启用,覆盖板设置为将物品从存储空间输出至管道时将阻止物品从所在面输入。/n§a已启用 cover.conveyor.blocks_input.disabled=若启用,覆盖板设置为将物品从存储空间输出至管道时将阻止物品从所在面输入。/n§c已禁用 cover.universal.manual_import_export.mode.disabled=特殊I/O模式:禁用 @@ -1290,6 +1316,7 @@ cover.conveyor.item_filter.title=物品过滤 cover.conveyor.ore_dictionary.title=矿物词典 cover.conveyor.ore_dictionary.title2=(*可作通配符) cover.robotic_arm.title=机械臂设置(%s) +cover.robotic_arm.exact=§7物品 cover.robotic_arm.transfer_mode.transfer_any=任意传输 cover.robotic_arm.transfer_mode.transfer_exact=精确补给 cover.robotic_arm.transfer_mode.keep_exact=保持补给 @@ -1300,8 +1327,12 @@ cover.pump.transfer_rate=%s cover.pump.mode.export=模式:输出 cover.pump.mode.import=模式:输入 cover.pump.fluid_filter.title=流体过滤 -cover.bucket.mode.bucket=kL/s -cover.bucket.mode.milli_bucket=L/s +cover.bucket.mode.bucket=流体单位:kL +cover.bucket.mode.milli_bucket=流体单位:L +cover.bucket.mode.bucket_rate=kL/s +cover.bucket.mode.bucket_exact=kL +cover.bucket.mode.milli_bucket_rate=L/s +cover.bucket.mode.milli_bucket_exact=L cover.fluid_regulator.title=流体校准器设置(%s) cover.fluid_regulator.transfer_mode.description=§e任意传输§r - 在此模式下,覆盖板将尽可能传输一切符合过滤设置的流体。/n§e精确供应-在此模式下,覆盖板会将此按钮下方窗口中指定的流体按指定量打包传输。若流体量小于指定量,流体不会被传输。/n§e保持供应-在此模式下,覆盖板将在目标容器中保持指定数量的液体,低于保持量时传输相应量的流体。/n§7小提示:按住Shift/Crtl把增加或减少的数量乘以10/100。 cover.fluid_regulator.supply_exact=精确补给:%s @@ -1324,7 +1355,7 @@ cover.machine_controller.disable_with_redstone=接收红石信号时关闭 cover.ender_fluid_link.title=末影流体连接 cover.ender_fluid_link.iomode.enabled=已启用I/O cover.ender_fluid_link.iomode.disabled=已禁用I/O -cover.ender_fluid_link.private.tooltip.disabled=切换至私有储罐模式/n私有权归最初加装该覆盖板的玩家所有 +cover.ender_fluid_link.private.tooltip.disabled=切换至私有储罐模式\n私有权归最初加装该覆盖板的玩家所有 cover.ender_fluid_link.private.tooltip.enabled=切换至公共储罐模式 cover.ender_fluid_link.incomplete_hex=输入的颜色不正确!/n输入正确的八位十六进制颜色码方可应用/n此时关闭界面将导致丢失编辑内容! @@ -2400,9 +2431,9 @@ behavior.tricorder.machine_progress=处理进度/总计:%s / %s behavior.tricorder.energy_container_in=输入上限:%s(%s)EU,%s A behavior.tricorder.energy_container_out=输出上限:%s(%s)EU,%s A behavior.tricorder.energy_container_storage=电量:%s EU / %s EU -behavior.tricorder.bedrock_fluid.amount=流体蕴含量:%s %s - %s%% -behavior.tricorder.bedrock_fluid.amount_unknown=流体蕴含量:%s%% -behavior.tricorder.bedrock_fluid.nothing=流体蕴含量:§6无§r +behavior.tricorder.bedrock_fluid.amount=流体储量:%s %s - %s%% +behavior.tricorder.bedrock_fluid.amount_unknown=流体储量:%s%% +behavior.tricorder.bedrock_fluid.nothing=流体储量:§6无§r behavior.tricorder.eut_per_sec=最后一秒 %s EU/t behavior.tricorder.amp_per_sec=最后一秒 %s A behavior.tricorder.workable_progress=处理进度:%s s / %s s @@ -5105,13 +5136,13 @@ gregtech.machine.rotor_holder.zpm.name=§cZPM§r转子支架 gregtech.machine.rotor_holder.uv.name=§3UV§r转子支架 gregtech.machine.maintenance_hatch.name=维护仓 -gregtech.machine.maintenance_hatch.tooltip=用以对多方块机器进行维护 +gregtech.machine.maintenance_hatch.tooltip=用以对多方块结构进行维护 gregtech.machine.maintenance_hatch_configurable.name=可配置维护仓 gregtech.machine.maintenance_hatch_configurable.tooltip=更精细的维修多方块结构/n起手无需维护! gregtech.machine.maintenance_hatch_full_auto.name=自动维护仓 -gregtech.machine.maintenance_hatch_full_auto.tooltip=可以自动维修多方块机器 +gregtech.machine.maintenance_hatch_full_auto.tooltip=可以自动维修多方块结构 gregtech.machine.maintenance_hatch_cleanroom_auto.name=自动过滤维护仓 -gregtech.machine.maintenance_hatch_cleanroom_auto.tooltip.1=可以自动维修多方块机器,附带清洁功能! +gregtech.machine.maintenance_hatch_cleanroom_auto.tooltip.1=可以自动维修多方块结构,附带清洁功能! gregtech.machine.maintenance_hatch.cleanroom_auto.tooltip.2=清洁方式: gregtech.machine.maintenance_hatch_tool_slot.tooltip=所需工具处于物品栏时空手点击该槽位来进行维护 gregtech.machine.maintenance_hatch_tape_slot.tooltip=放入胶带以防止发生故障 @@ -5283,6 +5314,11 @@ gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中 gregtech.machine.me.fluid_export.tooltip.2=可以缓存无限数量的流体 gregtech.machine.me.stocking_auto_pull_enabled=ME自动拉取已启用 gregtech.machine.me.stocking_auto_pull_disabled=ME自动拉取已禁用 +gregtech.machine.me.copy_paste.tooltip=左键点击闪存以复制设置,右键点击以应用 +gregtech.machine.me.import_copy_settings=已将设置保存到闪存 +gregtech.machine.me.import_paste_settings=已从闪存应用设置 +gregtech.machine.me.item_import.data_stick.name=§oME输入总线配置数据 +gregtech.machine.me.fluid_import.data_stick.name=§oME输入仓配置数据 # Universal tooltips gregtech.universal.tooltip.voltage_in=§a输入电压:§f%,d EU/t(%s§f) @@ -5342,6 +5378,7 @@ gregtech.recipe.temperature=温度:%,dK(%s) gregtech.recipe.explosive=爆炸物:%s gregtech.recipe.eu_to_start=启动耗能:%sEU gregtech.recipe.dimensions=维度:%s +gregtech.recipe.dimensions_blocked=禁用维度:%s gregtech.recipe.cleanroom=需要%s gregtech.recipe.cleanroom.display_name=超净间 gregtech.recipe.cleanroom_sterile.display_name=无菌超净间 @@ -5685,7 +5722,7 @@ gregtech.multiblock.power_substation.passive_drain=被动损失:%s gregtech.multiblock.power_substation.average_in=平均EU输入:%s gregtech.multiblock.power_substation.average_out=平均EU输出:%s gregtech.multiblock.power_substation.average_in_hover=蓄能变电站内部的平均功率输入 -gregtech.multiblock.power_substation.average_out_hover=蓄能变电站内部的平均功率输出 +gregtech.multiblock.power_substation.average_out_hover=蓄能变电站内部的平均功率输出,包括被动损耗和输出 gregtech.multiblock.power_substation.time_to_fill=预计充满时间:%s gregtech.multiblock.power_substation.time_to_drain=预计耗空时间:%s gregtech.multiblock.power_substation.time_seconds=%s秒 @@ -5951,7 +5988,7 @@ terminal.store.close=关闭 terminal.ar.open=开启AR -terminal.multiblock_ar.description=还记得§c自由扳手§r吗?不好意思,它和我们说拜拜了。但是问题不大,现在我们手里掌握着一种新兴的科技。这款应用程序能够协助你搭建多方块机器。 +terminal.multiblock_ar.description=还记得§c自由扳手§r吗?不好意思,它和我们说拜拜了。但是问题不大,现在我们手里掌握着一种新兴的科技。这款应用程序能够协助你搭建多方块结构。 terminal.multiblock_ar.tier.0=AR相机 terminal.multiblock_ar.tier.1=3D搭建器 terminal.multiblock_ar.unlock=升级后方可解锁该模式 From 9015d5db9876f106d739bdbe1d7b8a4cba6102cf Mon Sep 17 00:00:00 2001 From: Tictim Date: Tue, 7 May 2024 10:16:33 +0900 Subject: [PATCH 122/168] Fusion bloom fix & other bloom effect API modifications (#2470) (cherry picked from commit d006d607f87d000cf444d550ebec217e95911e7c) --- .../client/event/ClientEventHandler.java | 7 + .../client/particle/GTOverheatParticle.java | 10 +- .../client/utils/BloomEffectUtil.java | 158 +++++++++++++++--- .../client/utils/EffectRenderContext.java | 16 ++ .../gregtech/client/utils/IBloomEffect.java | 9 +- .../electric/MetaTileEntityFusionReactor.java | 8 +- 6 files changed, 177 insertions(+), 31 deletions(-) diff --git a/src/main/java/gregtech/client/event/ClientEventHandler.java b/src/main/java/gregtech/client/event/ClientEventHandler.java index c83851d8e34..f4ac14d8bfd 100644 --- a/src/main/java/gregtech/client/event/ClientEventHandler.java +++ b/src/main/java/gregtech/client/event/ClientEventHandler.java @@ -11,6 +11,7 @@ import gregtech.client.renderer.handler.BlockPosHighlightRenderer; import gregtech.client.renderer.handler.MultiblockPreviewRenderer; import gregtech.client.renderer.handler.TerminalARRenderer; +import gregtech.client.utils.BloomEffectUtil; import gregtech.client.utils.DepthTextureUtil; import gregtech.client.utils.TooltipHelper; import gregtech.common.ConfigHolder; @@ -24,6 +25,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.*; +import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.EventPriority; @@ -157,4 +159,9 @@ private static void renderHUDMetaItem(@NotNull ItemStack stack) { } } } + + @SubscribeEvent + public static void onWorldUnload(WorldEvent.Unload event) { + BloomEffectUtil.invalidateWorldTickets(event.getWorld()); + } } diff --git a/src/main/java/gregtech/client/particle/GTOverheatParticle.java b/src/main/java/gregtech/client/particle/GTOverheatParticle.java index d017af7b3a0..8736b628798 100644 --- a/src/main/java/gregtech/client/particle/GTOverheatParticle.java +++ b/src/main/java/gregtech/client/particle/GTOverheatParticle.java @@ -251,7 +251,15 @@ public void renderBloomEffect(@NotNull BufferBuilder buffer, @NotNull EffectRend @Override public boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { - return !this.insulated; + if (this.insulated) return false; + for (Cuboid6 cuboid : pipeBoxes) { + if (!context.camera().isBoxInFrustum( + cuboid.min.x + posX, cuboid.min.y + posY, cuboid.min.z + posZ, + cuboid.max.x + posX, cuboid.max.y + posY, cuboid.max.z + posZ)) { + return false; + } + } + return true; } private static final IRenderSetup SETUP = new IRenderSetup() { diff --git a/src/main/java/gregtech/client/utils/BloomEffectUtil.java b/src/main/java/gregtech/client/utils/BloomEffectUtil.java index 2dcc7d0be14..c4a4e0548ee 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectUtil.java @@ -20,6 +20,7 @@ import net.minecraft.entity.Entity; import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockRenderLayer; +import net.minecraft.world.World; import net.minecraftforge.common.util.EnumHelper; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -38,8 +39,10 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; @SideOnly(Side.CLIENT) public class BloomEffectUtil { @@ -47,6 +50,8 @@ public class BloomEffectUtil { private static final Map> BLOOM_RENDERS = new Object2ObjectOpenHashMap<>(); private static final List SCHEDULED_BLOOM_RENDERS = new ArrayList<>(); + private static final ReentrantLock BLOOM_RENDER_LOCK = new ReentrantLock(); + /** * @deprecated use {@link #getBloomLayer()} */ @@ -147,12 +152,12 @@ public static Framebuffer getBloomFBO() { /** *

* Register a custom bloom render callback for subsequent world render. The render call persists until the - * {@code metaTileEntity} is invalidated, or the ticket is manually freed by calling - * {@link BloomRenderTicket#invalidate()}. + * {@code metaTileEntity} is invalidated, or the world associated with {@code metaTileEntity} or the ticket is + * manually freed by calling {@link BloomRenderTicket#invalidate()}. *

*

- * This method does not register bloom render ticket when Optifine is present, and {@code null} will be returned - * instead of a ticket instance. + * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. *

* * @param setup Render setup, if exists @@ -162,13 +167,28 @@ public static Framebuffer getBloomFBO() { * @return Ticket for the registered bloom render callback * @throws NullPointerException if {@code bloomType == null || render == null || metaTileEntity == null} */ - @Nullable + @NotNull public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, @NotNull BloomType bloomType, @NotNull IBloomEffect render, @NotNull MetaTileEntity metaTileEntity) { Objects.requireNonNull(metaTileEntity, "metaTileEntity == null"); - return registerBloomRender(setup, bloomType, render, t -> metaTileEntity.isValid()); + return registerBloomRender(setup, bloomType, + new IBloomEffect() { + + @Override + public void renderBloomEffect(@NotNull BufferBuilder buffer, @NotNull EffectRenderContext context) { + render.renderBloomEffect(buffer, context); + } + + @Override + public boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { + return metaTileEntity.getWorld() == context.renderViewEntity().world && + render.shouldRenderBloomEffect(context); + } + }, + t -> metaTileEntity.isValid(), + metaTileEntity::getWorld); } /** @@ -178,8 +198,8 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * {@link BloomRenderTicket#invalidate()}. *

*

- * This method does not register bloom render ticket when Optifine is present, and {@code null} will be returned - * instead of a ticket instance. + * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. *

* * @param setup Render setup, if exists @@ -189,7 +209,7 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * @return Ticket for the registered bloom render callback * @throws NullPointerException if {@code bloomType == null || render == null || metaTileEntity == null} */ - @Nullable + @NotNull public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, @NotNull BloomType bloomType, @NotNull IBloomEffect render, @@ -204,8 +224,8 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * manually freed by calling {@link BloomRenderTicket#invalidate()}, or invalidated by validity checker. *

*

- * This method does not register bloom render ticket when Optifine is present, and {@code null} will be returned - * instead of a ticket instance. + * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. *

* * @param setup Render setup, if exists @@ -215,18 +235,85 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * Checked on both pre/post render each frame. * @return Ticket for the registered bloom render callback * @throws NullPointerException if {@code bloomType == null || render == null} + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, MetaTileEntity) + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, GTParticle) + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, Predicate, Supplier) */ - @Nullable + @NotNull public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, @NotNull BloomType bloomType, @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { - if (Mods.Optifine.isModLoaded()) return null; - BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker); - SCHEDULED_BLOOM_RENDERS.add(ticket); + return registerBloomRender(setup, bloomType, render, validityChecker, null); + } + + /** + *

+ * Register a custom bloom render callback for subsequent world render. The render call persists until it is + * manually freed by calling {@link BloomRenderTicket#invalidate()}, or invalidated by validity checker. + *

+ *

+ * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. + *

+ * + * @param setup Render setup, if exists + * @param bloomType Type of the bloom + * @param render Rendering callback + * @param validityChecker Optional validity checker; returning {@code false} causes the ticket to be invalidated. + * Checked on both pre/post render each frame. + * @param worldContext Optional world bound to the ticket. If the world returned is not null, the bloom ticket + * will be automatically invalidated on world unload. If world context returns {@code null}, + * it will not be affected by aforementioned automatic invalidation. + * @return Ticket for the registered bloom render callback + * @throws NullPointerException if {@code bloomType == null || render == null} + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, MetaTileEntity) + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, GTParticle) + */ + @NotNull + public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, + @NotNull BloomType bloomType, + @NotNull IBloomEffect render, + @Nullable Predicate validityChecker, + @Nullable Supplier worldContext) { + if (Mods.Optifine.isModLoaded()) return BloomRenderTicket.INVALID; + BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker, worldContext); + BLOOM_RENDER_LOCK.lock(); + try { + SCHEDULED_BLOOM_RENDERS.add(ticket); + } finally { + BLOOM_RENDER_LOCK.unlock(); + } return ticket; } + /** + * Invalidate tickets associated with given world. + * + * @param world World + */ + public static void invalidateWorldTickets(@NotNull World world) { + Objects.requireNonNull(world, "world == null"); + BLOOM_RENDER_LOCK.lock(); + try { + for (BloomRenderTicket ticket : SCHEDULED_BLOOM_RENDERS) { + if (ticket.isValid() && ticket.worldContext != null && ticket.worldContext.get() == world) { + ticket.invalidate(); + } + } + + for (Map.Entry> e : BLOOM_RENDERS.entrySet()) { + for (BloomRenderTicket ticket : e.getValue()) { + if (ticket.isValid() && ticket.worldContext != null && ticket.worldContext.get() == world) { + ticket.invalidate(); + } + } + } + } finally { + BLOOM_RENDER_LOCK.unlock(); + } + } + /** * @deprecated use ticket-based bloom render hooks */ @@ -281,14 +368,26 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, BlockRenderLayer blockRenderLayer, // 70% sure it's translucent uh yeah double partialTicks, int pass, - Entity entity) { - Minecraft mc = Minecraft.getMinecraft(); - mc.profiler.endStartSection("BTLayer"); + @NotNull Entity entity) { + Minecraft.getMinecraft().profiler.endStartSection("BTLayer"); if (Mods.Optifine.isModLoaded()) { return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } + BLOOM_RENDER_LOCK.lock(); + try { + return renderBloomInternal(renderGlobal, blockRenderLayer, partialTicks, pass, entity); + } finally { + BLOOM_RENDER_LOCK.unlock(); + } + } + + private static int renderBloomInternal(RenderGlobal renderGlobal, + BlockRenderLayer blockRenderLayer, + double partialTicks, + int pass, + @NotNull Entity entity) { preDraw(); EffectRenderContext context = EffectRenderContext.getInstance().update(entity, (float) partialTicks); @@ -309,7 +408,7 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } - Framebuffer fbo = mc.getFramebuffer(); + Framebuffer fbo = Minecraft.getMinecraft().getFramebuffer(); if (bloomFBO == null || bloomFBO.framebufferWidth != fbo.framebufferWidth || @@ -360,12 +459,12 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, // reset transparent layer render state and render OpenGlHelper.glBindFramebuffer(OpenGlHelper.GL_FRAMEBUFFER, fbo.framebufferObject); GlStateManager.enableBlend(); - mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GlStateManager.shadeModel(GL11.GL_SMOOTH); int result = renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); - mc.profiler.endStartSection("bloom"); + Minecraft.getMinecraft().profiler.endStartSection("bloom"); // blend bloom + transparent fbo.bindFramebufferTexture(); @@ -492,29 +591,44 @@ private record BloomRenderKey(@Nullable IRenderSetup renderSetup, @NotNull Bloom public static final class BloomRenderTicket { + public static final BloomRenderTicket INVALID = new BloomRenderTicket(); + @Nullable private final IRenderSetup renderSetup; private final BloomType bloomType; private final IBloomEffect render; @Nullable private final Predicate validityChecker; + @Nullable + private final Supplier worldContext; private boolean invalidated; + BloomRenderTicket() { + this(null, BloomType.DISABLED, (b, c) -> {}, null, null); + this.invalidated = true; + } + BloomRenderTicket(@Nullable IRenderSetup renderSetup, @NotNull BloomType bloomType, - @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { + @NotNull IBloomEffect render, @Nullable Predicate validityChecker, + @Nullable Supplier worldContext) { this.renderSetup = renderSetup; this.bloomType = Objects.requireNonNull(bloomType, "bloomType == null"); this.render = Objects.requireNonNull(render, "render == null"); this.validityChecker = validityChecker; + this.worldContext = worldContext; } @Nullable + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public IRenderSetup getRenderSetup() { return this.renderSetup; } @NotNull + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public BloomType getBloomType() { return this.bloomType; } diff --git a/src/main/java/gregtech/client/utils/EffectRenderContext.java b/src/main/java/gregtech/client/utils/EffectRenderContext.java index e5b63b69feb..bee87a7a85a 100644 --- a/src/main/java/gregtech/client/utils/EffectRenderContext.java +++ b/src/main/java/gregtech/client/utils/EffectRenderContext.java @@ -1,6 +1,8 @@ package gregtech.client.utils; import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.culling.ClippingHelperImpl; +import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.entity.Entity; import net.minecraft.util.math.Vec3d; @@ -20,6 +22,9 @@ public static EffectRenderContext getInstance() { return instance; } + private final ClippingHelperImpl clippingHelper = new ClippingHelperImpl(); + private final Frustum camera = new Frustum(this.clippingHelper); + @Nullable private Entity renderViewEntity; private float partialTicks; @@ -53,6 +58,9 @@ public EffectRenderContext update(@NotNull Entity renderViewEntity, float partia this.rotationXY = ActiveRenderInfo.getRotationXY(); this.rotationXZ = ActiveRenderInfo.getRotationXZ(); + this.clippingHelper.init(); + this.camera.setPosition(this.cameraX, this.cameraY, this.cameraZ); + return this; } @@ -134,4 +142,12 @@ public float rotationXY() { public float rotationXZ() { return rotationXZ; } + + /** + * @return camera + */ + @NotNull + public Frustum camera() { + return camera; + } } diff --git a/src/main/java/gregtech/client/utils/IBloomEffect.java b/src/main/java/gregtech/client/utils/IBloomEffect.java index 2d3052ce09d..0e345794f3d 100644 --- a/src/main/java/gregtech/client/utils/IBloomEffect.java +++ b/src/main/java/gregtech/client/utils/IBloomEffect.java @@ -9,8 +9,11 @@ import org.jetbrains.annotations.NotNull; +import java.util.function.Predicate; + /** - * Render callback interface for {@link BloomEffectUtil#registerBloomRender(IRenderSetup, BloomType, IBloomEffect)}. + * Render callback interface for + * {@link BloomEffectUtil#registerBloomRender(IRenderSetup, BloomType, IBloomEffect, Predicate)}. */ @FunctionalInterface public interface IBloomEffect { @@ -26,8 +29,8 @@ public interface IBloomEffect { /** * @param context render context - * @return if this effect should be rendered; returning {@code false} skips {@link #renderBloomEffect(BufferBuilder, - * EffectRenderContext)} call. + * @return if this effect should be rendered; returning {@code false} skips + * {@link #renderBloomEffect(BufferBuilder, EffectRenderContext)} call. */ @SideOnly(Side.CLIENT) default boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 35c06785bab..6b735dcc96c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -691,18 +691,20 @@ public void renderBloomEffect(@NotNull BufferBuilder buffer, @NotNull EffectRend EnumFacing.Axis axis = RelativeDirection.UP.getRelativeFacing(getFrontFacing(), getUpwardsFacing(), isFlipped()) .getAxis(); + buffer.begin(GL11.GL_QUAD_STRIP, DefaultVertexFormats.POSITION_COLOR); RenderBufferHelper.renderRing(buffer, getPos().getX() - context.cameraX() + relativeBack.getXOffset() * 7 + 0.5, getPos().getY() - context.cameraY() + relativeBack.getYOffset() * 7 + 0.5, getPos().getZ() - context.cameraZ() + relativeBack.getZOffset() * 7 + 0.5, 6, 0.2, 10, 20, r, g, b, a, axis); + Tessellator.getInstance().draw(); } @Override @SideOnly(Side.CLIENT) public boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { - return this.hasFusionRingColor(); + return this.hasFusionRingColor() && context.camera().isBoundingBoxInFrustum(getRenderBoundingBox()); } @Override @@ -753,14 +755,10 @@ public void preDraw(@NotNull BufferBuilder buffer) { GlStateManager.color(1, 1, 1, 1); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240.0F, 240.0F); GlStateManager.disableTexture2D(); - - buffer.begin(GL11.GL_QUAD_STRIP, DefaultVertexFormats.POSITION_COLOR); } @Override public void postDraw(@NotNull BufferBuilder buffer) { - Tessellator.getInstance().draw(); - GlStateManager.enableTexture2D(); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lastBrightnessX, lastBrightnessY); } From ed99845585d4a7272c777727aabd7676b9e2fb9f Mon Sep 17 00:00:00 2001 From: htmlcsjs <46023024+htmlcsjs@users.noreply.github.com> Date: Tue, 7 May 2024 02:19:36 +0100 Subject: [PATCH 123/168] Inital Vintagium Support (#2463) Co-authored-by: kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> (cherry picked from commit 8c2f0c6e72bb5e500552f2ec11309f763275471b) --- .gitignore | 2 + dependencies.gradle | 12 +++++ src/main/java/gregtech/GregTechMod.java | 5 +++ src/main/java/gregtech/api/util/Mods.java | 2 + .../gregtech/asm/GregTechTransformer.java | 18 ++++++++ .../asm/visitors/VintagiumManagerVistor.java | 24 ++++++++++ .../visitors/VintagiumPassManagerVisitor.java | 35 +++++++++++++++ .../utils/BloomEffectVintagiumUtil.java | 45 +++++++++++++++++++ 8 files changed, 143 insertions(+) create mode 100644 src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java create mode 100644 src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java create mode 100644 src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java diff --git a/.gitignore b/.gitignore index 755fbb2ab6d..c2fb66e1e33 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ local.properties run/ logs/ + +libs/ diff --git a/dependencies.gradle b/dependencies.gradle index 4ab81db91bd..3ad6226cf1b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -57,6 +57,18 @@ dependencies { compileOnly rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 compileOnly rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 + // Special Vintagium Hackery + // Vintagium is currently only distributed as a .zip containing the reobf and -dev jars on Github Actions, which is not ideal + // Using a fake Ivy repo to download it does not work, as nightly.link does not support http HEAD requests, which Gradle wants + mkdir("libs") + // Using Gradle's Ant integration seems to be the least hacky way to download an arbitrary file without a plugin + ant.get(src: "https://nightly.link/Asek3/sodium-1.12/workflows/gradle/12.x%2Fforge/Vintagium.zip", + dest: "libs", + skipexisting: 'true') + ant.unzip(src: "libs/Vintagium.zip", + dest: "libs") + compileOnly(files("libs/vintagium-mc1.12.2-0.1-dev.jar")) + // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 5116e9b1018..2de8b3d1fb4 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -4,7 +4,9 @@ import gregtech.api.GregTechAPI; import gregtech.api.modules.ModuleContainerRegistryEvent; import gregtech.api.persistence.PersistentData; +import gregtech.api.util.Mods; import gregtech.client.utils.BloomEffectUtil; +import gregtech.client.utils.BloomEffectVintagiumUtil; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; @@ -45,6 +47,9 @@ public GregTechMod() { FluidRegistry.enableUniversalBucket(); if (FMLCommonHandler.instance().getSide().isClient()) { BloomEffectUtil.init(); + if (Mods.Vintagium.isModLoaded()) { + BloomEffectVintagiumUtil.init(); + } } } diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java index c022672f095..b06b7d9f247 100644 --- a/src/main/java/gregtech/api/util/Mods.java +++ b/src/main/java/gregtech/api/util/Mods.java @@ -68,6 +68,7 @@ public enum Mods { TOPAddons(Names.TOP_ADDONS), VoxelMap(Names.VOXEL_MAP), XaerosMinimap(Names.XAEROS_MINIMAP), + Vintagium(Names.VINTAGIUM), // Special Optifine handler, but consolidated here for simplicity Optifine(null) { @@ -135,6 +136,7 @@ public static class Names { public static final String TOP_ADDONS = "topaddons"; public static final String VOXEL_MAP = "voxelmap"; public static final String XAEROS_MINIMAP = "xaerominimap"; + public static final String VINTAGIUM = "vintagium"; } private final String ID; diff --git a/src/main/java/gregtech/asm/GregTechTransformer.java b/src/main/java/gregtech/asm/GregTechTransformer.java index 4bdf742b499..5f9d5e1ba3f 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -178,6 +178,24 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) ModelLoaderRegistryVisitor::new), ClassReader.EXPAND_FRAMES); return classWriter.toByteArray(); } + // TODO: Remove when vintagium has proper support for other rendering layers + case VintagiumPassManagerVisitor.TARGET_CLASS_NAME: { + ClassReader classReader = new ClassReader(basicClass); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + classReader.accept( + new TargetClassVisitor(classWriter, VintagiumPassManagerVisitor.TARGET_METHOD, + VintagiumPassManagerVisitor::new), + ClassReader.EXPAND_FRAMES); + return classWriter.toByteArray(); + } + case VintagiumManagerVistor.TARGET_CLASS_NAME: { + ClassReader classReader = new ClassReader(basicClass); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + classReader.accept( + new VintagiumManagerVistor(classWriter), + 0); + return classWriter.toByteArray(); + } } if (EnchantmentCanApplyVisitor.CLASS_TO_MAPPING_MAP.containsKey(internalName)) { ObfMapping methodMapping = EnchantmentCanApplyVisitor.CLASS_TO_MAPPING_MAP.get(internalName); diff --git a/src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java b/src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java new file mode 100644 index 00000000000..4d8d53edf47 --- /dev/null +++ b/src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java @@ -0,0 +1,24 @@ +package gregtech.asm.visitors; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Opcodes; + +public class VintagiumManagerVistor extends ClassVisitor implements Opcodes { + + public static final String TARGET_CLASS_NAME = "me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass"; + + public VintagiumManagerVistor(ClassVisitor cv) { + super(ASM5, cv); + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { + // Make BlockRenderPass.VALUES and BlockRenderPass.COUNT not final + if (name.equals("VALUES") || name.equals("COUNT")) { + return super.visitField(access & ~ACC_FINAL, name, desc, signature, value); + } else { + return super.visitField(access, name, desc, signature, value); + } + } +} diff --git a/src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java b/src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java new file mode 100644 index 00000000000..eb103ffb651 --- /dev/null +++ b/src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java @@ -0,0 +1,35 @@ +package gregtech.asm.visitors; + +import gregtech.asm.util.ObfMapping; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class VintagiumPassManagerVisitor extends MethodVisitor implements Opcodes { + + public static final String TARGET_CLASS_NAME = "me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager"; + public static final ObfMapping TARGET_METHOD = new ObfMapping(TARGET_CLASS_NAME, "createDefaultMappings", + "()Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager;"); + public static final ObfMapping GET_BLOOM_LAYER = new ObfMapping("gregtech/client/utils/BloomEffectUtil", + "getBloomLayer", "()Lnet/minecraft/util/BlockRenderLayer;"); + public static final ObfMapping GET_BLOOM_PASS = new ObfMapping("gregtech/client/utils/BloomEffectVintagiumUtil", + "getBloomPass", "()Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass;"); + public static final ObfMapping ADD_MAPPING = new ObfMapping(TARGET_CLASS_NAME, "addMapping", + "(Lnet/minecraft/util/BlockRenderLayer;Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass;)V"); + + public VintagiumPassManagerVisitor(MethodVisitor mv) { + super(ASM5, mv); + } + + @Override + public void visitInsn(int opcode) { + // add mapper.addMapping(BloomEffectUtil.getBloomLayer(), BloomEffectVintagiumUtil.getBloomPass()); + if (opcode == ARETURN) { + GET_BLOOM_LAYER.visitMethodInsn(this, INVOKESTATIC); + GET_BLOOM_PASS.visitMethodInsn(this, INVOKESTATIC); + ADD_MAPPING.visitMethodInsn(this, INVOKESPECIAL); + super.visitVarInsn(ALOAD, 0); + } + super.visitInsn(opcode); + } +} diff --git a/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java new file mode 100644 index 00000000000..ced8de12e03 --- /dev/null +++ b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java @@ -0,0 +1,45 @@ +package gregtech.client.utils; + +import net.minecraft.util.BlockRenderLayer; +import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; +import me.jellysquid.mods.sodium.client.util.BufferSizeUtil; +import me.jellysquid.mods.sodium.client.util.EnumUtil; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Field; +import java.util.Objects; + +@SideOnly(Side.CLIENT) +public class BloomEffectVintagiumUtil { + + private static BlockRenderPass bloom; + + public static void init() { + EnumUtil.LAYERS = BlockRenderLayer.values(); + BufferSizeUtil.BUFFER_SIZES.put(BloomEffectUtil.getBloomLayer(), 131072); + bloom = EnumHelper.addEnum(BlockRenderPass.class, "BLOOM", + new Class[] { BlockRenderLayer.class, boolean.class }, BloomEffectUtil.getBloomLayer(), true); + + try { + Field values = BlockRenderPass.class.getField("VALUES"); + values.set(null, BlockRenderPass.values()); + Field count = BlockRenderPass.class.getField("COUNT"); + count.set(null, BlockRenderPass.values().length); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** + * @return {@link BlockRenderPass} instance for the bloom render layer. + */ + @NotNull + @SuppressWarnings("unused") + public static BlockRenderPass getBloomPass() { + return Objects.requireNonNull(bloom, "Bloom effect is not initialized yet"); + } +} From 1d3044093b804c0c94b7e32a440e7ebf995fd0b3 Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Tue, 7 May 2024 11:30:46 +1000 Subject: [PATCH 124/168] Fix Ore Dict Ingredients When Changing OreDicts with CT & GS (#2456) (cherry picked from commit e0a246503cd14f012f0f19c4899e3cc4a256de4d) --- .../recipes/ingredients/GTRecipeOreInput.java | 24 ++++++++++++++++--- .../java/gregtech/common/CommonProxy.java | 10 ++++++++ .../groovy/GroovyScriptModule.java | 10 ++++++++ .../jei/JustEnoughItemsModule.java | 4 ++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java b/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java index e36d9e39370..a742a23c819 100644 --- a/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java +++ b/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java @@ -7,12 +7,19 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.Objects; public class GTRecipeOreInput extends GTRecipeInput { + // Standard forces a refresh of the input stack cache + // Used in GroovyScript Reload, and to avoid race conditions with CraftTweaker. + // Short.MAX_VALUE should be enough for the amount of times this is loaded + // (1 without GroovyScript Reload, Amount of GroovyScript Reloads otherwise) + private static short STANDARD = 0; + private short currentStandard; private final int ore; private ItemStack[] inputStacks; @@ -88,12 +95,15 @@ public GTRecipeInput copyWithAmount(int amount) { return copy; } - // The items returned here are not updated after its first call, so they are not suitable for use while recipes are - // being processed and + // The items returned here are not updated after its first call, unless standard is changed, + // so they are not suitable for use while recipes are being processed and // the OreDicts being modified. @Override public ItemStack[] getInputStacks() { - if (this.inputStacks == null) { + // Standard forces a refresh of the input stack cache. + // Used in GroovyScript Reload, and upon Load Complete to fix unreliable behaviour with CT and GS scripts. + if (inputStacks == null || currentStandard != STANDARD) { + currentStandard = STANDARD; inputStacks = (OreDictionary.getOres(OreDictionary.getOreName(ore)).stream().map(is -> { is = is.copy(); is.setCount(this.amount); @@ -163,4 +173,12 @@ public String toString() { // noinspection StringConcatenationMissingWhitespace return amount + "x" + OreDictionary.getOreName(ore); } + + /** + * Forces a Refresh of every GTRecipeOreInput's Stack Cache. + */ + @ApiStatus.Internal + public static void refreshStackCache() { + STANDARD++; + } } diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index b9927847cd4..3c474d5edc9 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -8,6 +8,7 @@ import gregtech.api.items.toolitem.IGTTool; import gregtech.api.recipes.GTRecipeInputCache; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.recipes.recipeproperties.FusionEUToStartProperty; import gregtech.api.terminal.TerminalRegistry; import gregtech.api.unification.material.Material; @@ -33,10 +34,12 @@ import gregtech.common.pipelike.laser.ItemBlockLaserPipe; import gregtech.common.pipelike.optical.BlockOpticalPipe; import gregtech.common.pipelike.optical.ItemBlockOpticalPipe; +import gregtech.integration.groovy.GroovyScriptModule; import gregtech.loaders.MaterialInfoLoader; import gregtech.loaders.OreDictionaryLoader; import gregtech.loaders.recipe.CraftingComponent; import gregtech.loaders.recipe.GTRecipeManager; +import gregtech.modules.GregTechModules; import net.minecraft.block.Block; import net.minecraft.item.Item; @@ -399,6 +402,13 @@ public void onPostLoad() { public void onLoadComplete() { GTRecipeInputCache.disableCache(); + + // If JEI and GS is not loaded, refresh ore dict ingredients + // Not needed if JEI is loaded, as done in the JEI plugin (and this runs after that) + // Not needed if GS is loaded, as done after script loads (and this runs after that) + if (!GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_JEI) && + !GroovyScriptModule.isCurrentlyRunning()) + GTRecipeOreInput.refreshStackCache(); } public boolean isFancyGraphics() { diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index 62891a1f132..bbeab52bf0c 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -8,6 +8,7 @@ import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.Element; import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; @@ -40,6 +41,7 @@ import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.event.ScriptRunEvent; import com.cleanroommc.groovyscript.gameobjects.GameObjectHandler; import com.cleanroommc.groovyscript.helper.EnumHelper; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; @@ -83,6 +85,14 @@ public static void onRecipeEvent(RegistryEvent.Register event) { GroovyScriptModule.loadMetaItemBracketHandler(); } + @SubscribeEvent + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) + public static void afterScriptLoad(ScriptRunEvent.Post event) { + // Not Needed if JEI Module is enabled + if (!GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_JEI)) + GTRecipeOreInput.refreshStackCache(); + } + public static boolean isCurrentlyRunning() { return GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_GRS) && GroovyScript.getSandbox().isRunning(); diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 35e3f525ec3..04a4adbe512 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -15,6 +15,7 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.category.GTRecipeCategory; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.recipes.machines.IScannerRecipeMap; import gregtech.api.recipes.machines.RecipeMapFurnace; @@ -279,6 +280,9 @@ public void register(IModRegistry registry) { }); registry.addIngredientInfo(new ItemStack(MetaBlocks.BRITTLE_CHARCOAL), VanillaTypes.ITEM, I18n.format("tile.brittle_charcoal.tooltip.1", I18n.format("tile.brittle_charcoal.tooltip.2"))); + + // Refresh Ore Ingredients Cache + GTRecipeOreInput.refreshStackCache(); } private void setupInputHandler() { From 0cc4d8079fa5114e8fe3451f329d1210da8e0096 Mon Sep 17 00:00:00 2001 From: tier940 Date: Thu, 25 Apr 2024 00:14:12 +0900 Subject: [PATCH 125/168] Update ja_JP lang for 2.8.8 (#2459) --- .../resources/assets/gregtech/lang/ja_jp.lang | 156 ++++++++++++------ 1 file changed, 108 insertions(+), 48 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/ja_jp.lang b/src/main/resources/assets/gregtech/lang/ja_jp.lang index 28cb715332c..b1564d9161a 100644 --- a/src/main/resources/assets/gregtech/lang/ja_jp.lang +++ b/src/main/resources/assets/gregtech/lang/ja_jp.lang @@ -1,7 +1,7 @@ # Japanese translate by MrKo_no & GTModpackTeam # 日本語ローカライズ担当: MrKo_no & GTModpackTeam -# Corresponding Version: 2.8.1 - beta -# 対応バージョン: 2.8.1 - beta +# Corresponding Version: 2.8.8 - beta +# 対応バージョン: 2.8.8 - beta death.attack.heat=%s は熱さを感じなくなった。 death.attack.frost=%s のふとんがふっとんだ。 @@ -50,8 +50,8 @@ gregtech.multiblock.steam.low_steam=蒸気不足! gregtech.multiblock.steam.steam_stored=蒸気: %s gregtech.machine.steam_hatch.name=蒸気用ハッチ gregtech.machine.steam.steam_hatch.tooltip=受入液体: §f蒸気 -gregtech.machine.steam_import_bus.name=蒸気用搬入バス -gregtech.machine.steam_export_bus.name=蒸気用搬出バス +gregtech.machine.steam_import_bus.name=搬入バス (蒸気用) +gregtech.machine.steam_export_bus.name=搬出バス (蒸気用) gregtech.machine.steam_bus.tooltip=非蒸気式のマルチブロックでは使用不可 gregtech.machine.steam_oven.name=蒸気式オーブン gregtech.multiblock.steam_oven.description=蒸気時代のマルチスメルター。ブロンズ製外装が最低6個必要。通常のハッチ/バスは使えず、専用の蒸気用のものが必要。蒸気ハッチは最下段に一つだけ置ける。 @@ -109,6 +109,21 @@ gregtech.top.ld_pipe_output=搬出 gregtech.top.ld_pipe_input_endpoint=搬入口: gregtech.top.ld_pipe_output_endpoint=搬出口: +option.gregtech.block_ore=鉱石ブロック +option.gregtech.controllable=機械の状態 +option.gregtech.converter=エネルギー変換機 +option.gregtech.diode=ダイオード +option.gregtech.energy=蓄電量 +option.gregtech.block_lamp=ランプ +option.gregtech.maintenance=メンテナンスの問題 +option.gregtech.multi_recipemap=機械モード +option.gregtech.multiblock=マルチブロック +option.gregtech.primitive_pump=初歩的なポンプ +option.gregtech.recipe_logic=レシピ +option.gregtech.steam_boiler=ボイラー +option.gregtech.transformer=変圧器 +option.gregtech.workable=進捗 + gregtech.waila.energy_stored=エネルギー: %d EU / %d EU gregtech.waila.progress_idle=停止中 gregtech.waila.progress_tick=進捗: %d t / %d t @@ -149,7 +164,7 @@ gregtech.tooltip.hold_ctrl=CTRLを押して詳細を表示 gregtech.tooltip.fluid_pipe_hold_shift=SHIFTで耐流体性能を表示 gregtech.tooltip.tool_fluid_hold_shift=SHIFTで耐流体性能とツール情報を表示 -metaitem.generic.fluid_container.tooltip=%,d/%,dL %s +metaitem.generic.fluid_container.tooltip=%3$s %1$,d/%2$,dL metaitem.generic.electric_item.tooltip=%,d/%,d EU - Tier %s metaitem.electric.discharge_mode.enabled=§e放電:有効 metaitem.electric.discharge_mode.disabled=§e放電:無効 @@ -1013,6 +1028,9 @@ item.gt.tool.screwdriver_lv.name=LVの%s製スクリュードライバー item.gt.tool.screwdriver_lv.tooltip=§8カバーと機械の設定に item.gt.tool.plunger.name=%s製ラバーカップ item.gt.tool.plunger.tooltip=§8機械から液体を撤去 +item.gt.tool.wire_cutter_lv.name=LVの%s製カッター +item.gt.tool.wire_cutter_hv.name=HVの%s製カッター +item.gt.tool.wire_cutter_iv.name=IVの%s製カッター item.gt.tool.tooltip.crafting_uses=§aあと§l%s§r§a回クラフトに利用できる @@ -1180,7 +1198,7 @@ cover.filter.blacklist.disabled=ホワイトリスト cover.filter.blacklist.enabled=ブラックリスト cover.ore_dictionary_filter.title=鉱石辞書フィルター -cover.ore_dictionary_filter.info=§b論理式の比較演算子/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r グループ化/n§6*§r ワイルドカード (0文字以上の任意文字列)/n§6?§r 任意の1文字/n§6()§r 空の項目(鉱石辞書がない項目も含む)に適合/n§6$c§r 大文字・小文字を区別する場合に式の先頭に付ける。/n§b例:/n§6dust*Gold | (plate* & !*Double*)/n全てのサイズの金の粉または全てのプレートが該当するが、二重プレートは該当しない。 +cover.ore_dictionary_filter.info=§b論理式の比較演算子/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r グループ化/n§6*§r ワイルドカード (0文字以上の任意文字列)/n§6?§r 任意の1文字/n§6()§r 空の項目(鉱石辞書がない項目も含む)に適合/n§6$c§r 大文字・小文字を区別する場合に式の先頭に付ける/n§b例:/n§6dust*Gold | (plate* & !*Double*)/n全てのサイズの金の粉または全てのプレートが該当するが、二重プレートは該当しない。 cover.ore_dictionary_filter.test_slot.info=フィルタ式に一致するかどうかのテスト用スロット cover.ore_dictionary_filter.test_slot.matches=§a* %s cover.ore_dictionary_filter.test_slot.matches_not=§c* %s @@ -1191,6 +1209,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s個のエラーと%s個の警 cover.ore_dictionary_filter.status.warn=§7%s個の警告 cover.ore_dictionary_filter.status.no_issues=§a問題ナシ cover.ore_dictionary_filter.status.explain=フィルターの合致状況: +cover.ore_dictionary_filter.button.case_sensitive.disabled=部分一致 +cover.ore_dictionary_filter.button.case_sensitive.enabled=完全一致 +cover.ore_dictionary_filter.button.match_all.disabled=複数の鉱石辞書のうちのどれか +cover.ore_dictionary_filter.button.match_all.enabled=複数の鉱石辞書全て cover.ore_dictionary_filter.preview.next=の次に右を含むもの: cover.ore_dictionary_filter.preview.match='%s' @@ -1305,11 +1327,6 @@ cover.fluid_regulator.transfer_mode.description=§eすべて移動§r - この cover.fluid_regulator.supply_exact=供給モード: %s cover.fluid_regulator.keep_exact=保持モード: %s -cover.machine_controller.title=機械制御設定 -cover.machine_controller.normal=通常 -cover.machine_controller.inverted=反転 -cover.machine_controller.inverted.description=§e通常§r - このモードは、設定した信号強度よりも弱い信号が入力されている時に機械が動作するようになります。/n§e反転§r - このモードは、設定した信号強度よりも強い信号が入力されている時に機械が動作するようになります。 -cover.machine_controller.redstone=最低レッドストーン信号強度: %,d cover.machine_controller.mode.machine=機械制御 cover.machine_controller.mode.cover_up=上面カバー制御 cover.machine_controller.mode.cover_down=下面カバー制御 @@ -1317,6 +1334,12 @@ cover.machine_controller.mode.cover_south=南面カバー制御 cover.machine_controller.mode.cover_north=北面カバー制御 cover.machine_controller.mode.cover_east=東面カバー制御 cover.machine_controller.mode.cover_west=西面カバー制御 +cover.machine_controller.this_cover=§cこのカバー +cover.machine_controller.cover_not_controllable=§c制御可能なカバーがない +cover.machine_controller.machine_not_controllable=§c機械が制御可能でない +cover.machine_controller.control=制御対象: +cover.machine_controller.enable_with_redstone=赤石信号で動作 +cover.machine_controller.disable_with_redstone=赤石信号で停止 cover.ender_fluid_link.title=液体エンダーリンク cover.ender_fluid_link.iomode.enabled=I/O 有効 @@ -1892,29 +1915,29 @@ gregtech.material.diesel=ディーゼル gregtech.material.rocket_fuel=ロケット燃料 gregtech.material.glue=ノリ gregtech.material.lubricant=潤滑剤 -gregtech.material.mc_guffium_239=Mc Guffium 239 +gregtech.material.mc_guffium_239=McGuffium 239 gregtech.material.indium_concentrate=濃縮インジウム gregtech.material.seed_oil=種油 gregtech.material.drilling_fluid=掘削油 gregtech.material.construction_foam=建築用フォーム -gregtech.material.oil=原油 -gregtech.material.oil_heavy=重油 -gregtech.material.oil_medium=原料油 -gregtech.material.oil_light=軽油 +gregtech.material.oil=石油 +gregtech.material.oil_heavy=石油 (高密度) +gregtech.material.oil_medium=石油 (中密度) +gregtech.material.oil_light=石油 (低密度) gregtech.material.natural_gas=天然ガス -gregtech.material.sulfuric_heavy_fuel=硫化重質燃料 -gregtech.material.heavy_fuel=重質燃料 -gregtech.material.lightly_hydrocracked_heavy_fuel=軽く水素で分解された重質燃料 -gregtech.material.severely_hydrocracked_heavy_fuel=十分に水素で分解された重質燃料 -gregtech.material.lightly_steamcracked_heavy_fuel=軽く蒸気で分解された重質燃料 -gregtech.material.severely_steamcracked_heavy_fuel=十分に蒸気で分解された重質燃料 -gregtech.material.sulfuric_light_fuel=硫化軽質燃料 -gregtech.material.light_fuel=軽質燃料 -gregtech.material.lightly_hydrocracked_light_fuel=軽く水素で分解された軽質燃料 -gregtech.material.severely_hydrocracked_light_fuel=十分に水素で分解された軽質燃料 -gregtech.material.lightly_steamcracked_light_fuel=軽く蒸気で分解された軽質燃料 -gregtech.material.severely_steamcracked_light_fuel=十分に蒸気で分解された軽質燃料 +gregtech.material.sulfuric_heavy_fuel=硫化重油 +gregtech.material.heavy_fuel=重油 +gregtech.material.lightly_hydrocracked_heavy_fuel=軽く水素で分解された重油 +gregtech.material.severely_hydrocracked_heavy_fuel=十分に水素で分解された重油 +gregtech.material.lightly_steamcracked_heavy_fuel=軽く蒸気で分解された重油 +gregtech.material.severely_steamcracked_heavy_fuel=十分に蒸気で分解された重油 +gregtech.material.sulfuric_light_fuel=硫化軽油 +gregtech.material.light_fuel=軽油 +gregtech.material.lightly_hydrocracked_light_fuel=軽く水素で分解された軽油 +gregtech.material.severely_hydrocracked_light_fuel=十分に水素で分解された軽油 +gregtech.material.lightly_steamcracked_light_fuel=軽く蒸気で分解された軽油 +gregtech.material.severely_steamcracked_light_fuel=十分に蒸気で分解された軽油 gregtech.material.sulfuric_naphtha=硫化ナフサ gregtech.material.naphtha=ナフサ gregtech.material.lightly_hydrocracked_naphtha=軽く水素で分解されたナフサ @@ -2049,8 +2072,8 @@ gregtech.material.naquadah_alloy=ナクアダ合金 gregtech.material.sulfuric_nickel_solution=硫酸ニッケル溶液 gregtech.material.sulfuric_copper_solution=硫酸銅溶液 gregtech.material.lead_zinc_solution=鉛-亜鉛溶液 -gregtech.material.diluted_sulfuric_acid=希硫酸 gregtech.material.nitration_mixture=ニトロ化混合物 +gregtech.material.diluted_sulfuric_acid=希硫酸 gregtech.material.diluted_hydrochloric_acid=希塩酸 gregtech.material.flint=火打石 gregtech.material.air=空気 @@ -2348,6 +2371,17 @@ tile.treated_wood_fence.name=防腐木材のフェンス tile.rubber_wood_fence_gate.name=ゴムの木材のフェンスゲート tile.treated_wood_fence_gate.name=防腐木材のフェンスゲート +tile.gt_explosive.breaking_tooltip=壊すと着火する。スニークしながら壊すと回収できる。 +tile.gt_explosive.lighting_tooltip=赤石信号では着火できない + +tile.powderbarrel.name=樽爆弾 +tile.powderbarrel.drops_tooltip=TNTよりほんの少し広範囲を破壊する。破壊されたものは全てドロップする。 +entity.Powderbarrel.name=樽爆弾 + +tile.itnt.name=工業用TNT +tile.itnt.drops_tooltip=TNTより広範囲を破壊する。破壊されたものは全てドロップする。 +entity.ITNT.name=工業用TNT + tile.brittle_charcoal.name=脆い木炭 tile.brittle_charcoal.tooltip.1=炭窯で製造される。 tile.brittle_charcoal.tooltip.2=採掘すると木炭を得られる。 @@ -2373,8 +2407,8 @@ metaitem.tricorder_scanner.tooltip=トライコーダー metaitem.debug_scanner.name=デバッグスキャナー metaitem.debug_scanner.tooltip=トライコーダー behavior.tricorder.position=----- X: %s Y: %s Z: %s D: %s ----- -behavior.tricorder.block_hardness=硬さ: %s / 爆破耐性: %s -behavior.tricorder.block_name=名称: %s / MetaData: %s +behavior.tricorder.block_hardness=硬さ: %s 爆破耐性: %s +behavior.tricorder.block_name=名称: %s MetaData: %s behavior.tricorder.state=%s: %s behavior.tricorder.divider========================== behavior.tricorder.tank=タンク %s: %s L / %s L %s @@ -2548,7 +2582,7 @@ tile.studs.green.name=緑色のスタッド tile.studs.red.name=赤のスタッド tile.studs.black.name=黒のスタッド -# Lampss(ON) +# Lamps(ON) tile.gregtech_lamp.white.name=白のランプ tile.gregtech_lamp.orange.name=橙色のランプ tile.gregtech_lamp.magenta.name=赤紫色のランプ @@ -4943,7 +4977,6 @@ gregtech.machine.item_bus.export.uhv.name=UHV搬出バス gregtech.bus.collapse_true=バス内でアイテムを整頓を行う gregtech.bus.collapse_false=バス内でアイテムを整頓を行わない -gregtech.bus.collapse.error=バスをマルチブロックに接続してください gregtech.machine.fluid_hatch.import.tooltip=マルチブロックへの液体搬入 @@ -5247,17 +5280,34 @@ gregtech.machine.laser_hatch.target.tooltip1=遠くからエネルギーを受 gregtech.machine.laser_hatch.tooltip2=§cレーザーケーブルは直線でなければなりません!!§7 gregtech.machine.fluid_tank.max_multiblock=最大サイズ: %,dx%,dx%,d -gregtech.machine.fluid_tank.fluid=内容物: %s L の %s - -gregtech.machine.me_export_fluid_hatch.name=ME 搬出ハッチ -gregtech.machine.me_export_item_bus.name=ME 搬出バス -gregtech.machine.me_import_fluid_hatch.name=ME在庫搬入ハッチ -gregtech.machine.me_import_item_bus.name=ME在庫搬入バス -gregtech.machine.me.fluid_export.tooltip=MEネットワークに液体を自動搬入 -gregtech.machine.me.item_export.tooltip=MEネットワークにアイテムを自動搬入 +gregtech.machine.fluid_tank.fluid=内容物:%2$s %1$s L + +# ME Parts //TODO +gregtech.machine.me_import_item_bus.name=ME 搬入バス +gregtech.machine.me.item_import.tooltip=特定のアイテムをMEネットワークから自動搬出 +gregtech.machine.me_stocking_item_bus.name=ME 在庫搬入バス +gregtech.machine.me.stocking_item.tooltip=MEネットワークからアイテムを直接受け取る +gregtech.machine.me.stocking_item.tooltip.2=MEモードからの自動搬入により、MEシステムの最初の16種類のアイテムが自動的に保持され、5秒ごとに更新される +gregtech.machine.me_import_item_hatch.configs.tooltip=16種類のアイテムを保持 +gregtech.machine.me_import_fluid_hatch.name=ME 搬入ハッチ gregtech.machine.me.fluid_import.tooltip=MEネットワークから液体を自動搬出 -gregtech.machine.me.item_import.tooltip=MEネットワークからアイテムを自動搬出 -gregtech.machine.me.export.tooltip=MEネットワーク接続前は無限の容量を持つ。 +gregtech.machine.me_stocking_fluid_hatch.name=ME 在庫搬入ハッチ +gregtech.machine.me.stocking_fluid.tooltip=MEネットワークからアイテムを直接受け取る +gregtech.machine.me.stocking_fluid.tooltip.2=MEモードからの自動搬入により、MEシステムの最初の16種類の液体が自動的に保持され、5秒ごとに更新される +gregtech.machine.me_import_fluid_hatch.configs.tooltip=16種類の液体を保持 +gregtech.machine.me_export_item_bus.name=ME 搬出バス +gregtech.machine.me.item_export.tooltip=MEネットワークにアイテムを直接保存 +gregtech.machine.me.item_export.tooltip.2=アイテム格納量は無限 +gregtech.machine.me_export_fluid_hatch.name=ME 搬出ハッチ +gregtech.machine.me.fluid_export.tooltip=MEネットワークに液体を直接保存 +gregtech.machine.me.fluid_export.tooltip.2=液体格納量は無限 +gregtech.machine.me.stocking_auto_pull_enabled=自動搬入を有効化 (現在は無効) +gregtech.machine.me.stocking_auto_pull_disabled=自動搬入を無効化 (現在は有効) +gregtech.machine.me.copy_paste.tooltip=左クリックでデータスティックの設定をコピー。右クリックで反映 +gregtech.machine.me.import_copy_settings=設定をデータスティックに保存しました +gregtech.machine.me.import_paste_settings=データスティックの設定を反映しました +gregtech.machine.me.item_import.data_stick.name=§oME 搬入バス設定データ +gregtech.machine.me.fluid_import.data_stick.name=§oME 搬出バス設定データ # Universal tooltips gregtech.universal.tooltip.voltage_in=§a入力電圧: §f%,d EU/t (%s§f) @@ -5376,9 +5426,12 @@ gregtech.gui.fluid_auto_output.tooltip.enabled=液体自動搬出を無効化 ( gregtech.gui.fluid_auto_output.tooltip.disabled=液体自動搬出を有効化 (現在は無効) gregtech.gui.item_auto_output.tooltip.enabled=アイテム自動搬出を無効化 (現在は有効) gregtech.gui.item_auto_output.tooltip.disabled=アイテム自動搬出を有効化 (現在は無効) +gregtech.gui.item_auto_collapse.tooltip.enabled=アイテムの整頓を有効化 (現在は無効) +gregtech.gui.item_auto_collapse.tooltip.disabled=アイテムの整頓を無効化 (現在は有効) gregtech.gui.charger_slot.tooltip=§f充電スロット§r/n%s§7バッテリーからエネルギーを吸い取る。§r/n%s§7の電動ツールとバッテリーを充電できる。 -gregtech.gui.configurator_slot.tooltip=§fプログラム回路スロット§r/n§a設定番号: §f%d§7/n/n§7右/左クリック/スクロールで値を変更する。/n§7シフト右クリックでやり直し。 +gregtech.gui.configurator_slot.tooltip=§fプログラム回路スロット§r\n§a設定番号: §f%d§7\n\n§7右/左クリック/スクロールで値を変更する。\n§7シフト左クリックで選択画面を表示。\n§7シフト右クリックでやり直し。 gregtech.gui.configurator_slot.no_value=なし +gregtech.gui.configurator_slot.unavailable.tooltip=プログラム回路スロットは使いません gregtech.gui.fluid_lock.tooltip.enabled=液体ロックを無効化 (現在は有効) gregtech.gui.fluid_lock.tooltip.disabled=液体ロックを有効化 (現在は無効) gregtech.gui.fluid_voiding.tooltip.enabled=超過分の廃棄を無効化 (現在は有効) @@ -5395,8 +5448,12 @@ gregtech.gui.me_network.offline=ネットワーク状態: §4オフライン§r gregtech.gui.waiting_list=送信待: gregtech.gui.config_slot=§f設定スロット§r gregtech.gui.config_slot.set=§7クリックで設定スロットを§b設定/選択§7。§r -gregtech.gui.config_slot.scroll=§7スクロールで設定量を§a変更§7。§r -gregtech.gui.config_slot.remove=§7右クリックで設定スロットを§4初期化§7。§r +gregtech.gui.config_slot.set_only=§7クリックして§b設定§7スロットをセット§r +gregtech.gui.config_slot.scroll=§7スクロールで設定量を§a変更§7§r +gregtech.gui.config_slot.remove=§7右クリックで設定スロットを§4初期化§7§r +gregtech.gui.config_slot.auto_pull_managed=§4無効化:§7 自動搬出により管理 +gregtech.gui.me_bus.extra_slot=追加スロット/n§7レシピの追加アイテムを置くスロット。例えば型やレンズなど +gregtech.gui.me_bus.auto_pull_button=MEからの自動アイテム引き出しを切り替えるためにクリック gregtech.gui.alarm.radius=半径: @@ -5650,8 +5707,10 @@ gregtech.multiblock.computation.not_enough_computation=計算力がたりない! gregtech.multiblock.power_substation.stored=蓄電量: %s gregtech.multiblock.power_substation.capacity=最大蓄電量: %s gregtech.multiblock.power_substation.passive_drain=損失量: %s -gregtech.multiblock.power_substation.average_io=平均入出力: %s -gregtech.multiblock.power_substation.average_io_hover=大型蓄電器の平均エネルギー変化量 +gregtech.multiblock.power_substation.average_in=平均入力量: %s +gregtech.multiblock.power_substation.average_out=平均出力量: %s +gregtech.multiblock.power_substation.average_in_hover=大型蓄電器への入力量の平均値 +gregtech.multiblock.power_substation.average_out_hover=大型蓄電器からの出力量と、損失量の合計の平均値。 gregtech.multiblock.power_substation.time_to_fill=満タンまで: %s gregtech.multiblock.power_substation.time_to_drain=枯渇まで: %s gregtech.multiblock.power_substation.time_seconds=%s 秒 @@ -6053,6 +6112,7 @@ metaitem.electrode.tin.name=錫の真空管 item.gt.tool.scoop.name=%s製虫取り網 item.gt.tool.behavior.scoop=§d樹木医: §f左クリックで蝶を捕獲 gt.tool.class.scoop=虫取り網 + # Drops item.gt.honey_drop.oil.name=石油の雫 item.gt.honey_drop.biomass.name=バイオマスの雫 From 27cb163e02e17ea8908d06c068a9d6e3a6f25783 Mon Sep 17 00:00:00 2001 From: alongstringofnumbers Date: Mon, 6 May 2024 22:02:34 -0700 Subject: [PATCH 126/168] 2.8.8 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0f5fa43458d..71338bd1ddb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.7-beta +modVersion=2.8.8-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From 89b2359f4b0bafbbb551914da11a4a830c19c573 Mon Sep 17 00:00:00 2001 From: kumquat-ir <66188216+kumquat-ir@users.noreply.github.com> Date: Tue, 7 May 2024 01:15:41 -0400 Subject: [PATCH 127/168] spotless issue --- .../multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java | 2 +- .../multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java | 2 +- .../java/gregtech/integration/groovy/GroovyScriptModule.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 8c939df5a72..3d4fea9abc0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -55,7 +55,7 @@ public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart, - IGhostSlotConfigurable, IDataStickIntractable { + IGhostSlotConfigurable, IDataStickIntractable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index 319498b12e8..4e510077787 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -46,7 +46,7 @@ import java.util.List; public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart, IDataStickIntractable { + implements IMultiblockAbilityPart, IDataStickIntractable { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index bbeab52bf0c..ab61bfb9e0a 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -268,7 +268,7 @@ public void onCompatLoaded(GroovyContainer groovyContainer) { .parser(IGameObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) .completer((paramIndex, items) -> { if (paramIndex != 0) return; - for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) { + for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext();) { var entry = iterator.next(); String mod = entry.getKey(); for (String key : entry.getValue().keySet()) { From 1ef997e03ea5577eafbbdd145dd227bcacdf2b06 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Sat, 1 Jun 2024 23:11:00 -0600 Subject: [PATCH 128/168] Fix the large turbine rotor texture (#2485) (cherry picked from commit f8c1a5281e6026a9df22fed3fef644b647e2aae2) --- .../large_turbine/rotor_spinning.png | Bin 3372 -> 2631 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/large_turbine/rotor_spinning.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/large_turbine/rotor_spinning.png index aae8d966cb4380903a9234e5b67c627456a255a6..e520608908a4b9b8d7e30a17a2a0b4b7901e4cf2 100644 GIT binary patch literal 2631 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 muyaF}OS(OE^aFaZ;Th)qH9>)+ Date: Sun, 2 Jun 2024 07:16:12 +0200 Subject: [PATCH 129/168] Small QoL Bee Update (#2458) (cherry picked from commit 00f3b4dc05800a81e77ddb58b4ec5f01090ccdb7) --- .../mutation/MaterialMutationCondition.java | 63 +++++++++++++++++++ .../resources/assets/gregtech/lang/en_us.lang | 3 + 2 files changed, 66 insertions(+) create mode 100644 src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java diff --git a/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java new file mode 100644 index 00000000000..a4ea54cdf23 --- /dev/null +++ b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java @@ -0,0 +1,63 @@ +package gregtech.integration.forestry.mutation; + +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.unification.material.Material; +import gregtech.api.util.LocalizationUtils; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.climate.IClimateProvider; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IMutationCondition; +import forestry.core.tiles.TileUtil; + +import java.util.HashSet; +import java.util.Set; + +import static org.apache.commons.lang3.StringUtils.capitalize; + +public class MaterialMutationCondition implements IMutationCondition { + + private final Set acceptedBlocks = new HashSet(); + private final String displayName; + + public MaterialMutationCondition(Material material) { + this.displayName = LocalizationUtils.format("gregtech.mutation.block_of", material.getLocalizedName()); + String oredictName = "block" + capitalize(material.getName()); + + for (ItemStack ore : OreDictUnifier.getAllWithOreDictionaryName(oredictName)) { + if (!ore.isEmpty()) { + Item oreItem = ore.getItem(); + Block oreBlock = Block.getBlockFromItem(oreItem); + if (oreBlock != Blocks.AIR) { + this.acceptedBlocks.addAll(oreBlock.getBlockState().getValidStates()); + } + } + } + } + + public float getChance(World world, BlockPos pos, IAllele allele0, IAllele allele1, IGenome genome0, + IGenome genome1, IClimateProvider climate) { + TileEntity tile; + do { + pos = pos.down(); + tile = TileUtil.getTile(world, pos); + } while (tile instanceof IBeeHousing); + + IBlockState blockState = world.getBlockState(pos); + return this.acceptedBlocks.contains(blockState) ? 1.0F : 0.0F; + } + + public String getDescription() { + return LocalizationUtils.format("for.mutation.condition.resource", this.displayName); + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 413e8033fbe..30c4c755015 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -6271,3 +6271,6 @@ gregtech.scanner.forestry.larvae=§oScanned Larvae gregtech.scanner.forestry.serum=§oScanned Serum gregtech.scanner.forestry.caterpillar=§oScanned Caterpillar gregtech.scanner.forestry.pollen=§oScanned Pollen + +# Mutation +gregtech.mutation.block_of=Block of %s From 9ed5f863e4396a0243dfabbbb35debd6b034b63f Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:24:18 -0600 Subject: [PATCH 130/168] Fix excessive packets & re-renders with AEHostable parts (#2487) (cherry picked from commit 9ce8a202bcad10fa938adb44bfdb4eb632e67b9a) --- .../multiblockpart/appeng/MetaTileEntityAEHostablePart.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java index 1c8f73e6837..60682eaea25 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java @@ -40,6 +40,7 @@ public abstract class MetaTileEntityAEHostablePart> extend private AENetworkProxy aeProxy; private int meUpdateTick; protected boolean isOnline; + protected boolean lastOnline; public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch, Class> storageChannel) { @@ -149,8 +150,9 @@ public boolean updateMEStatus() { } else { this.isOnline = false; } - if (!getWorld().isRemote) { + if (!getWorld().isRemote && this.isOnline != this.lastOnline) { writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(this.isOnline)); + this.lastOnline = this.isOnline; } return this.isOnline; } From 066d3fbb0829a918223c4fa71094b7a8d96cd0e4 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:40:51 -0600 Subject: [PATCH 131/168] Allow dynamic hatch placement on Distillation Tower (#2477) (cherry picked from commit 5c501fd838b1016e988fc48d4ad98decf901f0b4) --- .../metatileentities/MetaTileEntities.java | 2 +- .../MetaTileEntityDistillationTower.java | 177 +++++++++++++++++- 2 files changed, 168 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 4e57f3c5b93..12e325a6308 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -607,7 +607,7 @@ public static void init() { new MetaTileEntityImplosionCompressor(gregtechId("implosion_compressor"))); PYROLYSE_OVEN = registerMetaTileEntity(1004, new MetaTileEntityPyrolyseOven(gregtechId("pyrolyse_oven"))); DISTILLATION_TOWER = registerMetaTileEntity(1005, - new MetaTileEntityDistillationTower(gregtechId("distillation_tower"))); + new MetaTileEntityDistillationTower(gregtechId("distillation_tower"), true)); MULTI_FURNACE = registerMetaTileEntity(1006, new MetaTileEntityMultiSmelter(gregtechId("multi_furnace"))); LARGE_COMBUSTION_ENGINE = registerMetaTileEntity(1007, new MetaTileEntityLargeCombustionEngine(gregtechId("large_combustion_engine"), GTValues.EV)); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 553dae63de4..41e1da2ea88 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -1,13 +1,21 @@ package gregtech.common.metatileentities.multi.electric; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; @@ -15,8 +23,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiFluidHatch; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.state.IBlockState; @@ -26,25 +33,44 @@ import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.utils.FluidTankHandler; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; import static gregtech.api.util.RelativeDirection.*; public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController { + private final boolean useAdvHatchLogic; + + protected int layerCount; + protected List orderedFluidOutputs; + public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId) { + this(metaTileEntityId, false); + } + + public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId, boolean useAdvHatchLogic) { super(metaTileEntityId, RecipeMaps.DISTILLATION_RECIPES); + this.useAdvHatchLogic = useAdvHatchLogic; + if (useAdvHatchLogic) { + this.recipeMapWorkable = new DistillationTowerRecipeLogic(this); + } } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDistillationTower(metaTileEntityId); + return new MetaTileEntityDistillationTower(metaTileEntityId, this.useAdvHatchLogic); } @Override @@ -52,6 +78,10 @@ protected Function multiblockPartSorter() { return RelativeDirection.UP.getSorter(getFrontFacing(), getUpwardsFacing(), isFlipped()); } + /** + * Whether this multi can be rotated or face upwards.
+ * There will be consequences if this returns true. Go override {@link #determineOrderedFluidOutputs()} + */ @Override public boolean allowsExtendedFacing() { return false; @@ -74,7 +104,74 @@ protected void addDisplayText(List textList) { } @Override - protected BlockPattern createStructurePattern() { + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + if (!useAdvHatchLogic || this.structurePattern == null) return; + this.layerCount = determineLayerCount(this.structurePattern); + this.orderedFluidOutputs = determineOrderedFluidOutputs(); + } + + /** + * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @param structurePattern the structure pattern + * @return the number of layers that could hold output hatches + */ + protected int determineLayerCount(@NotNull BlockPattern structurePattern) { + return structurePattern.formedRepetitionCount[1] + 1; + } + + /** + * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @return the fluid hatches of the multiblock, in order, with null entries for layers that do not have hatches. + */ + protected List determineOrderedFluidOutputs() { + List fluidExportParts = this.getMultiblockParts().stream() + .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && + abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && + abilityPart instanceof MetaTileEntityMultiblockPart) + .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) + .collect(Collectors.toList()); + // the fluidExportParts should come sorted in smallest Y first, largest Y last. + List orderedHandlerList = new ObjectArrayList<>(); + int firstY = this.getPos().getY() + 1; + int exportIndex = 0; + for (int y = firstY; y < firstY + this.layerCount; y++) { + if (fluidExportParts.size() <= exportIndex) { + orderedHandlerList.add(null); + continue; + } + MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); + if (part.getPos().getY() == y) { + List hatchTanks = new ObjectArrayList<>(); + // noinspection unchecked + ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); + if (hatchTanks.size() == 1) + orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); + else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + exportIndex++; + } else if (part.getPos().getY() > y) { + orderedHandlerList.add(null); + } else { + GTLog.logger.error("The Distillation Tower at " + this.getPos() + + " had a fluid export hatch with an unexpected Y position."); + this.invalidateStructure(); + return new ObjectArrayList<>(); + } + } + return orderedHandlerList; + } + + @Override + public void invalidateStructure() { + super.invalidateStructure(); + this.layerCount = 0; + this.orderedFluidOutputs = null; + } + + @Override + protected @NotNull BlockPattern createStructurePattern() { return FactoryBlockPattern.start(RIGHT, FRONT, UP) .aisle("YSY", "YYY", "YYY") .aisle("XXX", "X#X", "XXX").setRepeatable(1, 11) @@ -85,11 +182,7 @@ protected BlockPattern createStructurePattern() { .or(abilities(MultiblockAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(3)) .or(abilities(MultiblockAbility.IMPORT_FLUIDS).setExactLimit(1))) .where('X', states(getCasingState()) - .or(metaTileEntities(MultiblockAbility.REGISTRY.get(MultiblockAbility.EXPORT_FLUIDS).stream() - .filter(mte -> !(mte instanceof MetaTileEntityMultiFluidHatch) && - !(mte instanceof MetaTileEntityMEOutputHatch)) - .toArray(MetaTileEntity[]::new)) - .setMinLayerLimited(1).setMaxLayerLimited(1)) + .or(abilities(MultiblockAbility.EXPORT_FLUIDS).setMaxLayerLimited(1, 1)) .or(autoAbilities(true, false))) .where('#', air()) .build(); @@ -124,6 +217,70 @@ protected ICubeRenderer getFrontOverlay() { @Override public int getFluidOutputLimit() { - return getOutputFluidInventory().getTanks(); + return this.layerCount; + } + + protected class DistillationTowerRecipeLogic extends MultiblockRecipeLogic { + + public DistillationTowerRecipeLogic(MetaTileEntityDistillationTower tileEntity) { + super(tileEntity); + } + + protected boolean applyFluidToOutputs(List fluids, boolean doFill) { + boolean valid = true; + for (int i = 0; i < fluids.size(); i++) { + IFluidHandler handler = orderedFluidOutputs.get(i); + // void if no hatch is found on that fluid's layer + // this is considered trimming and thus ignores canVoid + if (handler == null) continue; + int accepted = handler.fill(fluids.get(i), doFill); + if (accepted != fluids.get(i).amount) valid = false; + if (!doFill && !valid) break; + } + return valid; + } + + @Override + protected void outputRecipeOutputs() { + GTTransferUtils.addItemsToItemHandler(getOutputInventory(), false, itemOutputs); + this.applyFluidToOutputs(fluidOutputs, true); + } + + @Override + protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { + this.overclockResults = calculateOverclock(recipe); + + modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); + + if (!hasEnoughPower(overclockResults)) { + return false; + } + + IItemHandlerModifiable exportInventory = getOutputInventory(); + + // We have already trimmed outputs and chanced outputs at this time + // Attempt to merge all outputs + chanced outputs into the output bus, to prevent voiding chanced outputs + if (!metaTileEntity.canVoidRecipeItemOutputs() && + !GTTransferUtils.addItemsToItemHandler(exportInventory, true, recipe.getAllItemOutputs())) { + this.isOutputsFull = true; + return false; + } + + // Perform layerwise fluid checks + if (!metaTileEntity.canVoidRecipeFluidOutputs() && + !this.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { + this.isOutputsFull = true; + return false; + } + + this.isOutputsFull = false; + if (recipe.matches(true, importInventory, importFluids)) { + this.metaTileEntity.addNotifiedInput(importInventory); + return true; + } + return false; + } } } From c2731043c50dd6ee168fd6d0440f2fb2a498c5fd Mon Sep 17 00:00:00 2001 From: Zorbatron Date: Mon, 3 Jun 2024 23:14:45 -0400 Subject: [PATCH 132/168] Add a faster recipe for drilling fluid with distilled water (#2484) (cherry picked from commit 4d3a39efc64552bc992aa939484cf7c149f56867) --- .../gregtech/loaders/recipe/chemistry/MixerRecipes.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java index f4ae4d431af..d6ebaa3b9ac 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java @@ -102,6 +102,13 @@ public static void init() { .fluidOutputs(DrillingFluid.getFluid(5000)) .duration(64).EUt(16).buildAndRegister(); + MIXER_RECIPES.recipeBuilder() + .input(dust, Stone) + .fluidInputs(Lubricant.getFluid(20)) + .fluidInputs(DistilledWater.getFluid(4980)) + .fluidOutputs(DrillingFluid.getFluid(5000)) + .duration(48).EUt(16).buildAndRegister(); + MIXER_RECIPES.recipeBuilder().duration(160).EUt(VA[HV]) .input(dust, Beryllium) .input(dust, Potassium, 4) From 8485ac3852cde45996a36401b621a24e593d1157 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:28:28 -0400 Subject: [PATCH 133/168] fix pyrolyse speed (#2449) (cherry picked from commit 09e44d9a4390eff3d2742d0eada0b08db57e9df6) --- .../multi/electric/MetaTileEntityPyrolyseOven.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java index 15c3f450c0a..20dbb3d5ca5 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java @@ -180,8 +180,12 @@ protected void modifyOverclockPost(int[] resultOverclock, @NotNull IRecipeProper return; if (coilTier == 0) { - resultOverclock[1] *= 5.0 / 4; // 25% slower with cupronickel (coilTier = 0) - } else resultOverclock[1] *= 2.0f / (coilTier + 1); // each coil above kanthal (coilTier = 1) is 50% faster + // 75% speed with cupronickel (coilTier = 0) + resultOverclock[1] = 4 * resultOverclock[1] / 3; + } else { + // each coil above kanthal (coilTier = 1) is 50% faster + resultOverclock[1] = resultOverclock[1] * 2 / (coilTier + 1); + } resultOverclock[1] = Math.max(1, resultOverclock[1]); } From c70ac18e494785a624abe41ba5b21414f26fb8b8 Mon Sep 17 00:00:00 2001 From: Tian mi <35869948+MCTian-mi@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:46:36 +0800 Subject: [PATCH 134/168] Brute-force Fix of RAM Usage Problem When Using Alfheim (#2475) (cherry picked from commit ec756bbd72028945780601ffc04266c9135acb36) --- src/main/java/gregtech/api/util/Mods.java | 2 ++ .../gregtech/api/util/world/DummyWorld.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java index b06b7d9f247..609f71c1008 100644 --- a/src/main/java/gregtech/api/util/Mods.java +++ b/src/main/java/gregtech/api/util/Mods.java @@ -69,6 +69,7 @@ public enum Mods { VoxelMap(Names.VOXEL_MAP), XaerosMinimap(Names.XAEROS_MINIMAP), Vintagium(Names.VINTAGIUM), + Alfheim(Names.ALFHEIM), // Special Optifine handler, but consolidated here for simplicity Optifine(null) { @@ -137,6 +138,7 @@ public static class Names { public static final String VOXEL_MAP = "voxelmap"; public static final String XAEROS_MINIMAP = "xaerominimap"; public static final String VINTAGIUM = "vintagium"; + public static final String ALFHEIM = "alfheim"; } private final String ID; diff --git a/src/main/java/gregtech/api/util/world/DummyWorld.java b/src/main/java/gregtech/api/util/world/DummyWorld.java index 858a27138bb..451940347b9 100644 --- a/src/main/java/gregtech/api/util/world/DummyWorld.java +++ b/src/main/java/gregtech/api/util/world/DummyWorld.java @@ -1,5 +1,7 @@ package gregtech.api.util.world; +import gregtech.api.util.Mods; + import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.profiler.Profiler; @@ -10,6 +12,7 @@ import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.common.Optional.Method; import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import org.jetbrains.annotations.NotNull; @@ -37,6 +40,12 @@ public DummyWorld() { // De-allocate lightUpdateBlockList, checkLightFor uses this ObfuscationReflectionHelper.setPrivateValue(World.class, this, null, FMLLaunchHandler.isDeobfuscatedEnvironment() ? "lightUpdateBlockList" : "field_72994_J"); + + // De-allocate alfheim lighting engine + if (Mods.Alfheim.isModLoaded()) { + ObfuscationReflectionHelper.setPrivateValue(World.class, this, null, + "alfheim$lightingEngine"); + } } @Override @@ -90,4 +99,21 @@ protected boolean isChunkLoaded(int x, int z, boolean allowEmpty) { public boolean checkLightFor(@NotNull EnumSkyBlock lightType, @NotNull BlockPos pos) { return true; } + + @Override + @Method(modid = Mods.Names.ALFHEIM) + public World init() { + return this; + } + + @Override + @Method(modid = Mods.Names.ALFHEIM) + public int getLightFromNeighborsFor(EnumSkyBlock type, BlockPos pos) { + return 15; + } + + @Method(modid = Mods.Names.ALFHEIM) + public int alfheim$getLight(BlockPos pos, boolean checkNeighbors) { + return 15; + } } From e0d6dfdccf8c78e256f5e9971934a649dc7a3229 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:14:10 -0600 Subject: [PATCH 135/168] Clean up AEHostable part fix (#2488) (cherry picked from commit 97dd250a10531a1c596c9970bb84475650b9fd0d) --- .../appeng/MetaTileEntityAEHostablePart.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java index 60682eaea25..9084eeed969 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java @@ -40,7 +40,6 @@ public abstract class MetaTileEntityAEHostablePart> extend private AENetworkProxy aeProxy; private int meUpdateTick; protected boolean isOnline; - protected boolean lastOnline; public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch, Class> storageChannel) { @@ -102,8 +101,11 @@ public void receiveInitialSyncData(PacketBuffer buf) { public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_ONLINE_STATUS) { - this.isOnline = buf.readBoolean(); - scheduleRenderUpdate(); + boolean isOnline = buf.readBoolean(); + if (this.isOnline != isOnline) { + this.isOnline = isOnline; + scheduleRenderUpdate(); + } } } @@ -140,19 +142,17 @@ public void setFrontFacing(EnumFacing frontFacing) { public void gridChanged() {} /** - * Update me network connection status. + * Get the me network connection status, updating it if on serverside. * * @return the updated status. */ public boolean updateMEStatus() { - if (this.aeProxy != null) { - this.isOnline = this.aeProxy.isActive() && this.aeProxy.isPowered(); - } else { - this.isOnline = false; - } - if (!getWorld().isRemote && this.isOnline != this.lastOnline) { - writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(this.isOnline)); - this.lastOnline = this.isOnline; + if (!getWorld().isRemote) { + boolean isOnline = this.aeProxy != null && this.aeProxy.isActive() && this.aeProxy.isPowered(); + if (this.isOnline != isOnline) { + writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(isOnline)); + this.isOnline = isOnline; + } } return this.isOnline; } From d96f4abff46364ee0d7a9b395753930013d1cad8 Mon Sep 17 00:00:00 2001 From: Rundas <38040866+Rundas01@users.noreply.github.com> Date: Wed, 5 Jun 2024 19:06:46 +0200 Subject: [PATCH 136/168] Updating bees using the new Mutation Condition (#2486) (cherry picked from commit 72e2ef2aa8ee33004c0fefdeac213942221831c6) --- .../forestry/bees/GTBeeDefinition.java | 95 ++++++++++--------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 610c93e3d5f..82019c6c8c8 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -4,12 +4,12 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; -import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.Mods; import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.integration.forestry.ForestryModule; import gregtech.integration.forestry.ForestryUtil; +import gregtech.integration.forestry.mutation.MaterialMutationCondition; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -46,6 +46,7 @@ import java.util.function.Supplier; import static forestry.api.apiculture.EnumBeeChromosome.*; +import static gregtech.api.unification.material.Materials.*; public enum GTBeeDefinition implements IBeeDefinition { @@ -153,7 +154,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.INDUSTRIOUS, PEAT, 9); - mutation.requireResource("blockCoal"); + mutation.addMutationCondition(new MaterialMutationCondition(Coal)); }), OIL(GTBranchDefinition.GT_ORGANIC, "Oleum", true, 0x4C4C4C, 0x333333, beeSpecies -> { @@ -221,7 +222,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(ASH, COAL, 10); - mutation.requireResource("blockApatite"); + mutation.addMutationCondition(new MaterialMutationCondition(Apatite)); }), BIOMASS(GTBranchDefinition.GT_ORGANIC, "Taeda", true, 0x21E118, 0x17AF0E, beeSpecies -> { @@ -272,7 +273,7 @@ public enum GTBeeDefinition implements IBeeDefinition { dis -> { IBeeMutationBuilder mutation = dis.registerMutation(APATITE, ASH, 12); mutation.restrictTemperature(EnumTemperature.HOT); - mutation.requireResource("blockTricalciumPhosphate"); + mutation.addMutationCondition(new MaterialMutationCondition(TricalciumPhosphate)); }), SANDWICH(GTBranchDefinition.GT_ORGANIC, "Sandwico", true, 0x32CD32, 0xDAA520, beeSpecies -> { @@ -316,7 +317,7 @@ public enum GTBeeDefinition implements IBeeDefinition { dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.INDUSTRIOUS, BeeDefinition.DEMONIC, 10); - mutation.requireResource("blockRedstone"); + mutation.addMutationCondition(new MaterialMutationCondition(Redstone)); }), LAPIS(GTBranchDefinition.GT_GEM, "Lapidi", true, 0x1947D1, 0x476CDA, beeSpecies -> { @@ -328,7 +329,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.IMPERIAL, 10); - mutation.requireResource("blockLapis"); + mutation.addMutationCondition(new MaterialMutationCondition(Lapis)); }), CERTUS(GTBranchDefinition.GT_GEM, "Quarzeus", true, 0x57CFFB, 0xBBEEFF, beeSpecies -> { @@ -340,7 +341,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.HERMITIC, LAPIS, 10); - mutation.requireResource("blockCertusQuartz"); + mutation.addMutationCondition(new MaterialMutationCondition(CertusQuartz)); }), FLUIX(GTBranchDefinition.GT_GEM, "", true, 0xA375FF, 0xB591FF, beeSpecies -> { @@ -367,7 +368,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CERTUS, COAL, 3); - mutation.requireResource("blockDiamond"); + mutation.addMutationCondition(new MaterialMutationCondition(Diamond)); }), RUBY(GTBranchDefinition.GT_GEM, "Rubinus", false, 0xE6005C, 0xCC0052, beeSpecies -> { @@ -380,7 +381,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(REDSTONE, DIAMOND, 5); - mutation.requireResource("blockRuby"); + mutation.addMutationCondition(new MaterialMutationCondition(Ruby)); }), SAPPHIRE(GTBranchDefinition.GT_GEM, "Sapphirus", true, 0x0033CC, 0x00248F, beeSpecies -> { @@ -392,7 +393,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CERTUS, LAPIS, 5); - mutation.requireResource("blockSapphire"); + mutation.addMutationCondition(new MaterialMutationCondition(Sapphire)); }), OLIVINE(GTBranchDefinition.GT_GEM, "Olivinum", true, 0x248F24, 0xCCFFCC, beeSpecies -> { @@ -416,7 +417,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(OLIVINE, DIAMOND, 4); - mutation.requireResource("blockEmerald"); + mutation.addMutationCondition(new MaterialMutationCondition(Emerald)); }), SPARKLING(GTBranchDefinition.GT_GEM, "Vesperstella", true, 0x7A007A, 0xFFFFFF, beeSpecies -> { @@ -438,7 +439,7 @@ public enum GTBeeDefinition implements IBeeDefinition { IBeeMutationBuilder mutation = dis.registerMutation( ForestryUtil.getSpecies(Mods.MagicBees, "Withering"), ForestryUtil.getSpecies(Mods.MagicBees, "Draconic"), 1); - mutation.requireResource("blockNetherStar"); + mutation.addMutationCondition(new MaterialMutationCondition(NetherStar)); mutation.restrictBiomeType(BiomeDictionary.Type.END); }, Mods.MagicBees::isModLoaded), @@ -455,7 +456,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.MAJESTIC, CLAY, 13); - mutation.requireResource("blockCopper"); + mutation.addMutationCondition(new MaterialMutationCondition(Copper)); }), TIN(GTBranchDefinition.GT_METAL, "Stannum", true, 0xD4D4D4, 0xDDDDDD, beeSpecies -> { @@ -468,7 +469,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CLAY, BeeDefinition.DILIGENT, 13); - mutation.requireResource("blockTin"); + mutation.addMutationCondition(new MaterialMutationCondition(Tin)); }), LEAD(GTBranchDefinition.GT_METAL, "Plumbum", true, 0x666699, 0xA3A3CC, beeSpecies -> { @@ -481,7 +482,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(COAL, COPPER, 13); - mutation.requireResource("blockLead"); + mutation.addMutationCondition(new MaterialMutationCondition(Lead)); }), IRON(GTBranchDefinition.GT_METAL, "Ferrum", true, 0xDA9147, 0xDE9C59, beeSpecies -> { @@ -494,7 +495,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TIN, COPPER, 13); - mutation.requireResource("blockIron"); + mutation.addMutationCondition(new MaterialMutationCondition(Iron)); }), STEEL(GTBranchDefinition.GT_METAL, "Chalybe", true, 0x808080, 0x999999, beeSpecies -> { @@ -507,7 +508,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRON, COAL, 10); - mutation.requireResource("blockSteel"); + mutation.addMutationCondition(new MaterialMutationCondition(Steel)); mutation.restrictTemperature(EnumTemperature.HOT); }), NICKEL(GTBranchDefinition.GT_METAL, "Nichelium", true, 0x8585AD, 0x8585AD, @@ -521,7 +522,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRON, COPPER, 13); - mutation.requireResource("blockNickel"); + mutation.addMutationCondition(new MaterialMutationCondition(Nickel)); }), ZINC(GTBranchDefinition.GT_METAL, "Cadmiae", true, 0xF0DEF0, 0xF2E1F2, beeSpecies -> { @@ -534,7 +535,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRON, TIN, 13); - mutation.requireResource("blockZinc"); + mutation.addMutationCondition(new MaterialMutationCondition(Zinc)); }), SILVER(GTBranchDefinition.GT_METAL, "Argenti", true, 0xC2C2D6, 0xCECEDE, beeSpecies -> { @@ -547,7 +548,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LEAD, TIN, 10); - mutation.requireResource("blockSilver"); + mutation.addMutationCondition(new MaterialMutationCondition(Silver)); }), GOLD(GTBranchDefinition.GT_METAL, "Aurum", true, 0xEBC633, 0xEDCC47, beeSpecies -> { @@ -560,7 +561,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LEAD, COPPER, 13); - mutation.requireResource("blockGold"); + mutation.addMutationCondition(new MaterialMutationCondition(Gold)); mutation.restrictTemperature(EnumTemperature.HOT); }), ARSENIC(GTBranchDefinition.GT_METAL, "Arsenicum", true, 0x736C52, 0x292412, @@ -573,7 +574,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(ZINC, SILVER, 10); - mutation.requireResource("blockArsenic"); + mutation.addMutationCondition(new MaterialMutationCondition(Arsenic)); }), SILICON(GTBranchDefinition.GT_ORGANIC, "Silex", false, 0xADA2A7, 0x736675, beeSpecies -> { @@ -606,7 +607,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(NICKEL, ZINC, 9); - mutation.requireResource("blockAluminium"); + mutation.addMutationCondition(new MaterialMutationCondition(Aluminium)); }), TITANIUM(GTBranchDefinition.GT_RAREMETAL, "Titanus", true, 0xCC99FF, 0xDBB8FF, beeSpecies -> { @@ -619,7 +620,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(REDSTONE, ALUMINIUM, 5); - mutation.requireResource("blockTitanium"); + mutation.addMutationCondition(new MaterialMutationCondition(Titanium)); }), // todo glowstone? CHROME(GTBranchDefinition.GT_RAREMETAL, "Chroma", true, 0xEBA1EB, 0xF2C3F2, @@ -633,7 +634,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TITANIUM, RUBY, 5); - mutation.requireResource("blockChrome"); + mutation.addMutationCondition(new MaterialMutationCondition(Chrome)); }), MANGANESE(GTBranchDefinition.GT_RAREMETAL, "Manganum", true, 0xD5D5D5, 0xAAAAAA, beeSpecies -> { @@ -646,7 +647,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TITANIUM, ALUMINIUM, 5); - mutation.requireResource("blockManganese"); + mutation.addMutationCondition(new MaterialMutationCondition(Manganese)); }), TUNGSTEN(GTBranchDefinition.GT_RAREMETAL, "Wolframium", false, 0x5C5C8A, 0x7D7DA1, beeSpecies -> { @@ -659,7 +660,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.HEROIC, MANGANESE, 5); - mutation.requireResource("blockTungsten"); + mutation.addMutationCondition(new MaterialMutationCondition(Tungsten)); }), PLATINUM(GTBranchDefinition.GT_RAREMETAL, "Platina", false, 0xE6E6E6, 0xFFFFCC, beeSpecies -> { @@ -672,7 +673,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(DIAMOND, CHROME, 5); - mutation.requireResource("blockPlatinum"); + mutation.addMutationCondition(new MaterialMutationCondition(Platinum)); }), IRIDIUM(GTBranchDefinition.GT_RAREMETAL, "Iris", false, 0xDADADA, 0xD1D1E0, beeSpecies -> { @@ -686,7 +687,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TUNGSTEN, PLATINUM, 5); - mutation.requireResource("blockIridium"); + mutation.addMutationCondition(new MaterialMutationCondition(Iridium)); }), OSMIUM(GTBranchDefinition.GT_RAREMETAL, "Osmia", false, 0x2B2BDA, 0x8B8B8B, beeSpecies -> { @@ -700,7 +701,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TUNGSTEN, PLATINUM, 5); - mutation.requireResource("blockOsmium"); + mutation.addMutationCondition(new MaterialMutationCondition(Osmium)); }), SALTY(GTBranchDefinition.GT_RAREMETAL, "Sal", true, 0xF0C8C8, 0xFAFAFA, beeSpecies -> { @@ -713,7 +714,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CLAY, ALUMINIUM, 5); - mutation.requireResource("blockSalt"); + mutation.addMutationCondition(new MaterialMutationCondition(Salt)); }), LITHIUM(GTBranchDefinition.GT_RAREMETAL, "Lithos", false, 0xF0328C, 0xE1DCFF, beeSpecies -> { @@ -726,7 +727,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(SALTY, ALUMINIUM, 5); - mutation.requireResource("blockLithium"); + mutation.addMutationCondition(new MaterialMutationCondition(Lithium)); }), ELECTROTINE(GTBranchDefinition.GT_RAREMETAL, "Electrum", false, 0x1E90FF, 0x3CB4C8, beeSpecies -> { @@ -739,7 +740,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(REDSTONE, GOLD, 5); - mutation.requireResource("blockElectrotine"); + mutation.addMutationCondition(new MaterialMutationCondition(Electrotine)); }), SULFUR(GTBranchDefinition.GT_RAREMETAL, "Sulphur", false, 0x1E90FF, 0x3CB4C8, beeSpecies -> { @@ -759,7 +760,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWEST), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LEAD, OSMIUM, 1); - mutation.requireResource("blockIndium"); + mutation.addMutationCondition(new MaterialMutationCondition(Indium)); mutation.restrictBiomeType(BiomeDictionary.Type.END); }), @@ -793,7 +794,7 @@ public enum GTBeeDefinition implements IBeeDefinition { } else { mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.FIENDISH, 10); } - mutation.requireResource("blockRedstone"); + mutation.addMutationCondition(new MaterialMutationCondition(Redstone)); }), LAPOTRON(GTBranchDefinition.GT_INDUSTRIAL, "Azureus", false, 0xFFEBC4, 0xE36400, beeSpecies -> { @@ -815,7 +816,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LAPIS, ENERGY, 6); - mutation.requireResource("blockLapis"); + mutation.addMutationCondition(new MaterialMutationCondition(Lapis)); mutation.restrictTemperature(EnumTemperature.ICY); }), EXPLOSIVE(GTBranchDefinition.GT_INDUSTRIAL, "Explosionis", false, 0x7E270F, 0x747474, @@ -853,7 +854,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(COPPER, REDSTONE, 10); - mutation.requireResource("blockRedAlloy"); + mutation.addMutationCondition(new MaterialMutationCondition(RedAlloy)); }), STAINLESSSTEEL(GTBranchDefinition.GT_ALLOY, "Nonferrugo", false, 0xC8C8DC, 0x778899, beeSpecies -> { @@ -871,7 +872,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CHROME, STEEL, 9); - mutation.requireResource("blockStainlessSteel"); + mutation.addMutationCondition(new MaterialMutationCondition(StainlessSteel)); }), // Radioactive @@ -889,7 +890,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.AVENGING, PLATINUM, 2); - mutation.requireResource("blockUranium"); + mutation.addMutationCondition(new MaterialMutationCondition(Uranium238)); }), PLUTONIUM(GTBranchDefinition.GT_RADIOACTIVE, "Plutos", true, 0x570000, 0x240000, beeSpecies -> { @@ -906,7 +907,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(URANIUM, EMERALD, 2); - mutation.requireResource("blockPlutonium"); + mutation.addMutationCondition(new MaterialMutationCondition(Plutonium239)); }), NAQUADAH(GTBranchDefinition.GT_RADIOACTIVE, "Nasquis", false, 0x003300, 0x002400, beeSpecies -> { @@ -923,7 +924,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(PLUTONIUM, IRIDIUM, 1); - mutation.requireResource("blockNaquadah"); + mutation.addMutationCondition(new MaterialMutationCondition(Naquadah)); }), NAQUADRIA(GTBranchDefinition.GT_RADIOACTIVE, "Nasquidrius", false, 0x000000, 0x002400, beeSpecies -> { @@ -941,7 +942,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(PLUTONIUM, IRIDIUM, 1); - mutation.requireResource("blockNaquadria"); + mutation.addMutationCondition(new MaterialMutationCondition(Naquadria)); }), TRINIUM(GTBranchDefinition.GT_RADIOACTIVE, "Trinium", false, 0xB0E0E6, 0xC8C8D2, beeSpecies -> { @@ -955,7 +956,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, GTAlleleBeeSpecies.speedBlinding), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRIDIUM, NAQUADAH, 4); - mutation.requireResource("blockTrinium"); + mutation.addMutationCondition(new MaterialMutationCondition(Trinium)); }), THORIUM(GTBranchDefinition.GT_RADIOACTIVE, "Thorax", false, 0x005000, 0x001E00, beeSpecies -> { @@ -970,7 +971,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation = dis.registerMutation(COAL, URANIUM, 2).setIsSecret(); - mutation.requireResource("blockThorium"); + mutation.addMutationCondition(new MaterialMutationCondition(Thorium)); }), LUTETIUM(GTBranchDefinition.GT_RADIOACTIVE, "Lutetia", false, 0x00AAFF, 0x0059FF, beeSpecies -> { @@ -992,7 +993,7 @@ public enum GTBeeDefinition implements IBeeDefinition { mutation = dis.registerMutation(THORIUM, BeeDefinition.IMPERIAL, 1); } mutation.setIsSecret(); - mutation.requireResource("blockLutetium"); + mutation.addMutationCondition(new MaterialMutationCondition(Lutetium)); }), AMERICIUM(GTBranchDefinition.GT_RADIOACTIVE, "Libertas", false, 0x287869, 0x0C453A, beeSpecies -> { @@ -1008,7 +1009,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation = dis.registerMutation(LUTETIUM, CHROME, 1).setIsSecret(); - mutation.requireResource("blockAmericium"); + mutation.addMutationCondition(new MaterialMutationCondition(Americium)); }), NEUTRONIUM(GTBranchDefinition.GT_RADIOACTIVE, "Media", false, 0xFFF0F0, 0xFAFAFA, beeSpecies -> { @@ -1024,7 +1025,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation = dis.registerMutation(NAQUADRIA, AMERICIUM, 1).setIsSecret(); - mutation.requireResource(new UnificationEntry(OrePrefix.block, Materials.Neutronium).toString()); + mutation.addMutationCondition(new MaterialMutationCondition(Neutronium)); }), // Noble Gases From d0fe83d6e077e7ae3a800fe38fb0f587f8af6d3f Mon Sep 17 00:00:00 2001 From: serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:03:31 -0500 Subject: [PATCH 137/168] dependency updates (cherry picked from commit a68d66f38ed40bc3dbe3527663566fa0c8b83421) --- dependencies.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 3ad6226cf1b..70fa763ed88 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -42,16 +42,16 @@ dependencies { api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.4.3") { transitive = false } api("com.cleanroommc:groovyscript:1.0.1") { transitive = false } - api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") - api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.698") + api("appeng:ae2-uel:v0.56.4") { transitive = false } api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 // Non-published dependencies // Change any to devOnlyNonPublishable to test them in-game. - compileOnly("curse.maven:journeymap-32274:2916002") // Journeymap 5.7.1 + compileOnly("curse.maven:journeymap-32274:5172461") // Journeymap 5.7.1p3 compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 - compileOnly("curse.maven:xaeros-263420:4516832") // Xaero's Minimap 23.4.1 - compileOnly rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 + compileOnly("curse.maven:xaeros-263420:5394758") // Xaero's Minimap 24.2.0 + compileOnly rfg.deobf("curse.maven:opencomputers-223008:5274236") // OpenComputers 1.8.5+179e1c3 compileOnly rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 compileOnly rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 compileOnly rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 From cef91807dad5884b73ca2a73579f7347485965ce Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:13:46 -0500 Subject: [PATCH 138/168] Allow recipe logic to set EU/t and speed discounts (#2496) (cherry picked from commit 132a449a0cc8154be3b79826a4afd6239ead5360) --- .../capability/impl/AbstractRecipeLogic.java | 71 +++++++++ .../impl/AbstractRecipeLogicTest.java | 137 ++++++++++++------ 2 files changed, 163 insertions(+), 45 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index ce4eab33ac9..a5b8ae1fefc 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -13,10 +13,12 @@ import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; import gregtech.api.metatileentity.multiblock.ParallelLogicType; import gregtech.api.recipes.Recipe; +import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.logic.IParallelableRecipeLogic; import gregtech.api.recipes.recipeproperties.CleanroomProperty; import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; @@ -49,6 +51,9 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable, private final RecipeMap recipeMap; + private double euDiscount = -1; + private double speedBonus = -1; + protected Recipe previousRecipe; private boolean allowOverclocking = true; protected int parallelRecipesPerformed; @@ -450,6 +455,23 @@ public boolean prepareRecipe(Recipe recipe, IItemHandlerModifiable inputInventor recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); + // apply EU/speed discount (if any) before parallel + if (euDiscount > 0 || speedBonus > 0) { // if-statement to avoid unnecessarily creating RecipeBuilder object + RecipeBuilder builder = new RecipeBuilder<>(recipe, recipeMap); + if (euDiscount > 0) { + int newEUt = (int) Math.round(recipe.getEUt() * euDiscount); + if (newEUt <= 0) newEUt = 1; + builder.EUt(newEUt); + } + if (speedBonus > 0) { + int duration = recipe.getDuration(); + int newDuration = (int) Math.round(duration * speedBonus); + if (newDuration <= 0) newDuration = 1; + builder.duration(newDuration); + } + recipe = builder.build().getResult(); + } + // Pass in the trimmed recipe to the parallel logic recipe = findParallelRecipe( recipe, @@ -501,6 +523,55 @@ public void setParallelLimit(int amount) { parallelLimit = amount; } + /** + * Sets an EU/t discount to apply to a machine when running recipes.
+ * This does NOT affect recipe lookup voltage, even if the discount drops it to a lower voltage tier.
+ * This discount is applied pre-parallel/pre-overclock. + * + * @param discount The discount, must be greater than 0 and less than 1. + * If discount == 0.75, then the recipe will only require 75% of the listed power to run. + * If discount is > 1, then the recipe will require more than the listed power to run. + * Be careful as this may not always be possible within the EU/t maximums of the machine! + * + */ + public void setEUDiscount(double discount) { + if (discount <= 0) { + GTLog.logger.warn("Cannot set EU discount for recipe logic to {}, discount must be > 0", discount); + return; + } + euDiscount = discount; + } + + /** + * @return the EU/t discount, or -1 if no discount. + */ + public double getEUtDiscount() { + return euDiscount; + } + + /** + * Sets a speed multiplier to apply to a machine when running recipes.
+ * This discount is applied pre-parallel/pre-overclock. + * + * @param bonus The bonus, must be greater than 0. + * If bonus == 0.2, then the recipe will be 20% of the normal duration. + * If bonus is > 1, then the recipe will be slower than the normal duration. + */ + public void setSpeedBonus(double bonus) { + if (bonus <= 0) { + GTLog.logger.warn("Cannot set speed bonus for recipe logic to {}, bonus must be > 0", bonus); + return; + } + speedBonus = bonus; + } + + /** + * @return the speed bonus, or -1 if no bonus. + */ + public double getSpeedBonus() { + return speedBonus; + } + /** * @return the parallel logic type to use for recipes */ diff --git a/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java b/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java index 68ae9384de7..056f025c8e0 100644 --- a/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java +++ b/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java @@ -30,10 +30,93 @@ public static void bootstrap() { @Test public void trySearchNewRecipe() { + AbstractRecipeLogic arl = createTestLogic(1, 1); + arl.trySearchNewRecipe(); + + // no recipe found + MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(true)); + MatcherAssert.assertThat(arl.isActive, is(false)); + MatcherAssert.assertThat(arl.previousRecipe, nullValue()); + + queryTestRecipe(arl); + MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(false)); + MatcherAssert.assertThat(arl.previousRecipe, notNullValue()); + MatcherAssert.assertThat(arl.isActive, is(true)); + MatcherAssert.assertThat(arl.getInputInventory().getStackInSlot(0).getCount(), is(15)); + + // Save a reference to the old recipe so we can make sure it's getting reused + Recipe prev = arl.previousRecipe; + + // Finish the recipe, the output should generate, and the next iteration should begin + arl.update(); + MatcherAssert.assertThat(arl.previousRecipe, is(prev)); + MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), is(true)); + MatcherAssert.assertThat(arl.isActive, is(true)); + + // Complete the second iteration, but the machine stops because its output is now full + arl.getOutputInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 63)); + arl.getOutputInventory().setStackInSlot(1, new ItemStack(Blocks.STONE, 64)); + arl.update(); + MatcherAssert.assertThat(arl.isActive, is(false)); + MatcherAssert.assertThat(arl.isOutputsFull, is(true)); + + // Try to process again and get failed out because of full buffer. + arl.update(); + MatcherAssert.assertThat(arl.isActive, is(false)); + MatcherAssert.assertThat(arl.isOutputsFull, is(true)); + + // Some room is freed in the output bus, so we can continue now. + arl.getOutputInventory().setStackInSlot(1, ItemStack.EMPTY); + arl.update(); + MatcherAssert.assertThat(arl.isActive, is(true)); + MatcherAssert.assertThat(arl.isOutputsFull, is(false)); + MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), is(true)); + } + + @Test + public void euAndSpeedBonus() { + final int initialEUt = 30; + final int initialDuration = 100; + + AbstractRecipeLogic arl = createTestLogic(initialEUt, initialDuration); + arl.setEUDiscount(0.75); // 75% EU cost required + arl.setSpeedBonus(0.2); // 20% faster than normal + + queryTestRecipe(arl); + MatcherAssert.assertThat(arl.recipeEUt, is((int) Math.round(initialEUt * 0.75))); + MatcherAssert.assertThat(arl.maxProgressTime, is((int) Math.round(initialDuration * 0.2))); + } + + @Test + public void euAndSpeedBonusParallel() { + final int initialEUt = 30; + final int initialDuration = 100; + + AbstractRecipeLogic arl = createTestLogic(initialEUt, initialDuration); + arl.setEUDiscount(0.5); // 50% EU cost required + arl.setSpeedBonus(0.2); // 20% faster than normal + arl.setParallelLimit(4); // Allow parallels + + queryTestRecipe(arl); + + // The EU discount should drop the EU/t of this recipe to 15 EU/t. As a result, this should now + // be able to parallel 2 times. + MatcherAssert.assertThat(arl.parallelRecipesPerformed, is(2)); + // Because of the parallel, now the paralleled recipe EU/t should be back to 30 EU/t. + MatcherAssert.assertThat(arl.recipeEUt, is(30)); + // Duration should be static regardless of parallels. + MatcherAssert.assertThat(arl.maxProgressTime, is((int) Math.round(initialDuration * 0.2))); + } + + private static int TEST_ID = 190; + + private static AbstractRecipeLogic createTestLogic(int testRecipeEUt, int testRecipeDuration) { World world = DummyWorld.INSTANCE; // Create an empty recipe map to work with - RecipeMap map = new RecipeMap<>("test_reactor", + RecipeMap map = new RecipeMap<>("test_reactor_" + TEST_ID, 2, 2, 3, @@ -41,9 +124,9 @@ public void trySearchNewRecipe() { new SimpleRecipeBuilder().EUt(30), false); - MetaTileEntity at = MetaTileEntities.registerMetaTileEntity(190, + MetaTileEntity at = MetaTileEntities.registerMetaTileEntity(TEST_ID, new SimpleMachineMetaTileEntity( - GTUtility.gregtechId("chemical_reactor.lv"), + GTUtility.gregtechId("chemical_reactor.lv_" + TEST_ID), map, null, 1, false)); @@ -52,9 +135,11 @@ public void trySearchNewRecipe() { map.recipeBuilder() .inputs(new ItemStack(Blocks.COBBLESTONE)) .outputs(new ItemStack(Blocks.STONE)) - .EUt(1).duration(1) + .EUt(testRecipeEUt).duration(testRecipeDuration) .buildAndRegister(); + TEST_ID++; + AbstractRecipeLogic arl = new AbstractRecipeLogic(atte, map) { @Override @@ -85,51 +170,13 @@ public long getMaxVoltage() { arl.isOutputsFull = false; arl.invalidInputsForRecipes = false; - arl.trySearchNewRecipe(); - - // no recipe found - MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(true)); - MatcherAssert.assertThat(arl.isActive, is(false)); - MatcherAssert.assertThat(arl.previousRecipe, nullValue()); + return arl; + } + private static void queryTestRecipe(AbstractRecipeLogic arl) { // put an item in the inventory that will trigger recipe recheck arl.getInputInventory().insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false); - // Inputs change. did we detect it ? MatcherAssert.assertThat(arl.hasNotifiedInputs(), is(true)); arl.trySearchNewRecipe(); - MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(false)); - MatcherAssert.assertThat(arl.previousRecipe, notNullValue()); - MatcherAssert.assertThat(arl.isActive, is(true)); - MatcherAssert.assertThat(arl.getInputInventory().getStackInSlot(0).getCount(), is(15)); - - // Save a reference to the old recipe so we can make sure it's getting reused - Recipe prev = arl.previousRecipe; - - // Finish the recipe, the output should generate, and the next iteration should begin - arl.update(); - MatcherAssert.assertThat(arl.previousRecipe, is(prev)); - MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), - new ItemStack(Blocks.STONE, 1)), is(true)); - MatcherAssert.assertThat(arl.isActive, is(true)); - - // Complete the second iteration, but the machine stops because its output is now full - arl.getOutputInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 63)); - arl.getOutputInventory().setStackInSlot(1, new ItemStack(Blocks.STONE, 64)); - arl.update(); - MatcherAssert.assertThat(arl.isActive, is(false)); - MatcherAssert.assertThat(arl.isOutputsFull, is(true)); - - // Try to process again and get failed out because of full buffer. - arl.update(); - MatcherAssert.assertThat(arl.isActive, is(false)); - MatcherAssert.assertThat(arl.isOutputsFull, is(true)); - - // Some room is freed in the output bus, so we can continue now. - arl.getOutputInventory().setStackInSlot(1, ItemStack.EMPTY); - arl.update(); - MatcherAssert.assertThat(arl.isActive, is(true)); - MatcherAssert.assertThat(arl.isOutputsFull, is(false)); - MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), - new ItemStack(Blocks.STONE, 1)), is(true)); } } From 0e8f6d267e86a93aeb7a482f37875c6a19dede13 Mon Sep 17 00:00:00 2001 From: Zorbatron Date: Sat, 22 Jun 2024 00:21:35 -0400 Subject: [PATCH 139/168] Glass tube recycling (#2509) (cherry picked from commit b22bd7838acda9842ea8e58d3e3cc4b6b52e619e) --- src/main/java/gregtech/common/items/MetaItem1.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 9620ccaa60b..3dfe1ffb666 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -817,7 +817,8 @@ public void registerSubItems() { // Circuit Components: ID 516-565 VACUUM_TUBE = addItem(516, "circuit.vacuum_tube").setUnificationData(OrePrefix.circuit, Tier.ULV); - GLASS_TUBE = addItem(517, "component.glass.tube"); + GLASS_TUBE = addItem(517, "component.glass.tube") + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Glass, M))); TRANSISTOR = addItem(518, "component.transistor").setUnificationData(OrePrefix.component, Component.Transistor); RESISTOR = addItem(519, "component.resistor").setUnificationData(OrePrefix.component, Component.Resistor); CAPACITOR = addItem(520, "component.capacitor").setUnificationData(OrePrefix.component, Component.Capacitor); From 4b766785bb4e82f8953c5af8fc887cf985fa1c8e Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Fri, 21 Jun 2024 22:21:53 -0600 Subject: [PATCH 140/168] Improve assembly line laser render (#2495) (cherry picked from commit 2811c8ec40496da88bf7648d0f7f3162aa632047) --- .../client/particle/GTLaserBeamParticle.java | 26 ++++++++++++++++--- .../electric/MetaTileEntityAssemblyLine.java | 21 +++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java b/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java index d57f40af1df..f269bef42c2 100644 --- a/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java +++ b/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java @@ -13,6 +13,7 @@ import net.minecraft.client.renderer.texture.SimpleTexture; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import codechicken.lib.vec.Vector3; @@ -34,11 +35,20 @@ public class GTLaserBeamParticle extends GTParticle { private float emit; private boolean doubleVertical; + private int activeTime; + private final int fadeInTime; + public GTLaserBeamParticle(@Nullable MetaTileEntity mte, @NotNull Vector3 startPos, @NotNull Vector3 endPos) { + this(mte, startPos, endPos, 0); + } + + public GTLaserBeamParticle(@Nullable MetaTileEntity mte, @NotNull Vector3 startPos, @NotNull Vector3 endPos, + int fadeInTime) { super(startPos.x, startPos.y, startPos.z); this.mte = mte; this.direction = endPos.copy().subtract(startPos); this.setRenderRange(64); + this.fadeInTime = fadeInTime; } @Override @@ -99,6 +109,15 @@ public float getAlpha() { return this.alpha; } + public float getAlpha(float partialTicks) { + if (this.fadeInTime > this.activeTime) { + return (float) (this.alpha * MathHelper.clampedLerp( + (double) this.activeTime / this.fadeInTime, + (double) (this.activeTime + 1) / this.fadeInTime, partialTicks)); + } + return this.alpha; + } + /** * Set emit speed. * @@ -131,9 +150,8 @@ public void onUpdate() { if (mte == null || mte.isValid() && mte.getWorld().isBlockLoaded(mte.getPos(), false) && mte.getWorld().getTileEntity(mte.getPos()) == mte.getHolder()) { - return; - } - setExpired(); + this.activeTime++; + } else setExpired(); } @Override @@ -169,7 +187,7 @@ public void renderParticle(@NotNull BufferBuilder buffer, @NotNull EffectRenderC bodyTexture.getGlTextureId(), headTexture == null ? -1 : headTexture.getGlTextureId(), - direction, cameraDirection, beamHeight, headWidth, alpha, offset); + direction, cameraDirection, beamHeight, headWidth, this.getAlpha(context.partialTicks()), offset); GlStateManager.translate(context.cameraX() - posX, context.cameraY() - posY, context.cameraZ() - posZ); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java index 4432cd61a21..fb2de88df33 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java @@ -65,6 +65,7 @@ public class MetaTileEntityAssemblyLine extends RecipeMapMultiblockController { @SideOnly(Side.CLIENT) private GTLaserBeamParticle[][] beamParticles; private int beamCount; + private int beamTime; public MetaTileEntityAssemblyLine(ResourceLocation metaTileEntityId) { super(metaTileEntityId, RecipeMaps.ASSEMBLY_LINE_RECIPES); @@ -189,14 +190,22 @@ public void update() { // beams and the maximum progress in the recipe. int beamTime = Math.max(1, maxProgress / maxBeams); - int currentBeamCount = Math.min(maxBeams, getRecipeMapWorkable().getProgress() / beamTime); + int beamCount = Math.min(maxBeams, getRecipeMapWorkable().getProgress() / beamTime + 1); - if (currentBeamCount != beamCount) { - beamCount = currentBeamCount; + if (beamCount != this.beamCount) { + if (beamCount < this.beamCount) { + // if beam count decreases, the last beam in the queue needs to be removed for the sake of fade + // time. + this.beamCount = Math.max(0, beamCount - 1); + writeCustomData(GregtechDataCodes.UPDATE_PARTICLE, this::writeParticles); + } + this.beamTime = beamTime; + this.beamCount = beamCount; writeCustomData(GregtechDataCodes.UPDATE_PARTICLE, this::writeParticles); } } else if (beamCount != 0) { - beamCount = 0; + this.beamTime = 0; + this.beamCount = 0; writeCustomData(GregtechDataCodes.UPDATE_PARTICLE, this::writeParticles); } } @@ -239,11 +248,13 @@ public void onRemoval() { private void writeParticles(@NotNull PacketBuffer buf) { buf.writeVarInt(beamCount); + buf.writeVarInt(beamTime); } @SideOnly(Side.CLIENT) private void readParticles(@NotNull PacketBuffer buf) { beamCount = buf.readVarInt(); + beamTime = buf.readVarInt(); if (beamParticles == null) { beamParticles = new GTLaserBeamParticle[17][2]; } @@ -306,7 +317,7 @@ private void readParticles(@NotNull PacketBuffer buf) { @NotNull @SideOnly(Side.CLIENT) private GTLaserBeamParticle createALParticles(Vector3 startPos, Vector3 endPos) { - return new GTLaserBeamParticle(this, startPos, endPos) + return new GTLaserBeamParticle(this, startPos, endPos, beamTime) .setBody(LASER_LOCATION) .setBeamHeight(0.125f) // Try commenting or adjusting on the next four lines to see what happens From 1dca2cb111615b5b1c7ff081ee1485b85dd49fbc Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:45:36 +1000 Subject: [PATCH 141/168] Add Polybenzimidazole Block Conversion Recipes (#2511) (cherry picked from commit 981fbaa458d303a6f5486e5151771d3308e220d2) --- .../material/materials/OrganicChemistryMaterials.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java index de2bdf4a703..7bc82ca2805 100644 --- a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java @@ -97,7 +97,7 @@ public static void register() { .polymer() .liquid(new FluidBuilder().temperature(1450)) .color(0x2D2D2D) - .flags(EXCLUDE_BLOCK_CRAFTING_RECIPES, GENERATE_FOIL) + .flags(GENERATE_FOIL) .components(Carbon, 20, Hydrogen, 12, Nitrogen, 4) .fluidPipeProperties(1000, 350, true) .build(); From cdf0e8bded8d35554a5c62fe871559885589d81b Mon Sep 17 00:00:00 2001 From: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:12:59 -0700 Subject: [PATCH 142/168] GroovyScript 1.1.0 (#2506) (cherry picked from commit fe65538edbcb5ad4d7283c82ab1264f819d4c54b) --- dependencies.gradle | 2 +- src/main/java/gregtech/GregTechMod.java | 2 +- .../internal/MaterialRegistryManager.java | 5 +++ .../GroovyMaterialBuilderExpansion.java | 12 +++++-- .../groovy/GroovyScriptModule.java | 36 +++++++++---------- .../integration/groovy/PropertyContainer.java | 4 +-- .../groovy/VirtualizedRecipeMap.java | 2 +- 7 files changed, 35 insertions(+), 28 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 70fa763ed88..e2ef40e1819 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,7 +41,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.4.3") { transitive = false } - api("com.cleanroommc:groovyscript:1.0.1") { transitive = false } + api("com.cleanroommc:groovyscript:1.1.0") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.698") api("appeng:ae2-uel:v0.56.4") { transitive = false } api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 2de8b3d1fb4..254183d6d88 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -35,7 +35,7 @@ dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + "after:appliedenergistics2;" + "after:forestry;" + "after:extrabees;" + "after:extratrees;" + "after:genetics;" + "after:magicbees;" + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + - "after:groovyscript@[1.0.1,);" + "after:theoneprobe;" + "after:hwyla;") + "after:groovyscript@[1.1.0,);" + "after:theoneprobe;" + "after:hwyla;") public class GregTechMod { // Hold this so that we can reference non-interface methods without diff --git a/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java b/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java index 265e2a875d0..ff26e95cdd2 100644 --- a/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java +++ b/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java @@ -140,6 +140,11 @@ private MaterialRegistryImpl createInternalRegistry() { return registry; } + @NotNull + public MaterialRegistry getDefaultRegistry() { + return gregtechRegistry; + } + @NotNull public Material getDefaultFallback() { return gregtechRegistry.getFallbackMaterial(); diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index 2b67fa26844..f132c8ea481 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -108,10 +108,16 @@ public static Material.Builder components(Material.Builder builder, Object... ob materialStacks.add(materialStack); } else if (o instanceof Material material) { materialStacks.add(new MaterialStack(material, 1)); + } else if (o instanceof Integer) { + GroovyLog.msg("Error creating GregTech material") + .add("Tried to use old method for material components in the shape of (material1, amount1, material2, amount2)") + .add("Please change this into (material1 * amount1, material2 * amount2)") + .error().post(); } else { - GroovyLog.get() - .error("Material components must be of type Material or MaterialStack, but was of type {}", - o == null ? null : o.getClass()); + GroovyLog.msg("Error creating GregTech material") + .add("Material components must be of type Material or MaterialStack, but was of type {}", + o == null ? null : o.getClass()) + .error().post(); } } return builder.components(materialStacks.toArray(new MaterialStack[0])); diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index ab61bfb9e0a..cca6dc79bab 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -37,12 +37,11 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.GroovyPlugin; -import com.cleanroommc.groovyscript.api.IGameObjectParser; +import com.cleanroommc.groovyscript.api.IObjectParser; import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; -import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; import com.cleanroommc.groovyscript.event.ScriptRunEvent; -import com.cleanroommc.groovyscript.gameobjects.GameObjectHandler; import com.cleanroommc.groovyscript.helper.EnumHelper; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; @@ -118,6 +117,7 @@ public static > T parseAndValidateEnumValue(Class clazz, St return t; } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public static GroovyContainer getInstance() { return modSupportContainer; } @@ -238,34 +238,31 @@ public static void loadMetaItemBracketHandler() { @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override - public @Nullable ModPropertyContainer createModPropertyContainer() { + public @Nullable GroovyPropertyContainer createGroovyPropertyContainer() { return new PropertyContainer(); } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override - public void onCompatLoaded(GroovyContainer groovyContainer) { - GroovyScriptModule.modSupportContainer = groovyContainer; - GameObjectHandler.builder("recipemap", RecipeMap.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(RecipeMap::getByName)) + public void onCompatLoaded(GroovyContainer container) { + GroovyScriptModule.modSupportContainer = container; + container.objectMapperBuilder("recipemap", RecipeMap.class) + .parser(IObjectParser.wrapStringGetter(RecipeMap::getByName)) .completerOfNamed(RecipeMap::getRecipeMaps, RecipeMap::getUnlocalizedName) .register(); - GameObjectHandler.builder("material", Material.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) + container.objectMapperBuilder("material", Material.class) + .parser(IObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) .completerOfNamed(GregTechAPI.materialManager::getRegisteredMaterials, mat -> mat.getResourceLocation().toString()) .register(); - GameObjectHandler.builder("oreprefix", OrePrefix.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(OrePrefix::getPrefix)) + container.objectMapperBuilder("oreprefix", OrePrefix.class) + .parser(IObjectParser.wrapStringGetter(OrePrefix::getPrefix)) .completerOfNamed(OrePrefix::values, v -> v.name) .register(); - GameObjectHandler.builder("metaitem", ItemStack.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) + container.objectMapperBuilder("metaitem", ItemStack.class) + .parser(IObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) .completer((paramIndex, items) -> { if (paramIndex != 0) return; for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext();) { @@ -280,8 +277,7 @@ public void onCompatLoaded(GroovyContainer groovyContainer) { }) .register(); - GameObjectHandler.builder("element", Element.class) - .mod(GTValues.MODID) + container.objectMapperBuilder("element", Element.class) .parser((s, args) -> { Element element = Elements.get(s); if (element != null) return Result.some(element); diff --git a/src/main/java/gregtech/integration/groovy/PropertyContainer.java b/src/main/java/gregtech/integration/groovy/PropertyContainer.java index 35da8ce4905..30930c68f9c 100644 --- a/src/main/java/gregtech/integration/groovy/PropertyContainer.java +++ b/src/main/java/gregtech/integration/groovy/PropertyContainer.java @@ -7,7 +7,7 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; -import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; import com.cleanroommc.groovyscript.event.EventBusType; import com.cleanroommc.groovyscript.event.GroovyEventManager; import com.cleanroommc.groovyscript.sandbox.ClosureHelper; @@ -15,7 +15,7 @@ import groovy.lang.Closure; import groovy.lang.DelegatesTo; -public class PropertyContainer extends ModPropertyContainer { +public class PropertyContainer extends GroovyPropertyContainer { public void materialEvent(EventPriority priority, @DelegatesTo(MaterialEvent.class) Closure eventListener) { if (GroovyScriptModule.isCurrentlyRunning() && diff --git a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java index 6bd80f4db05..ff2e351d811 100644 --- a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java +++ b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java @@ -23,7 +23,7 @@ public class VirtualizedRecipeMap extends VirtualizedRegistry { public VirtualizedRecipeMap(RecipeMap recipeMap) { super(Alias.generateOf(recipeMap.unlocalizedName, CaseFormat.LOWER_UNDERSCORE)); this.recipeMap = recipeMap; - GroovyScriptModule.getInstance().getRegistrar().addRegistry(this); + GroovyScriptModule.getInstance().addProperty(this); } @Override From ec6b70ef2319fa6b0db1bbf148de5a7b975b0944 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:31:41 -0500 Subject: [PATCH 143/168] Fix liquid and gas registry key functions overlapping (#2514) Co-authored-by: TechLord22 <37029404+techlord22@users.noreply.github.com> (cherry picked from commit 375af9e03c5e8108480a110d9522d538bfbc3938) --- .../gregtech/api/fluids/FluidBuilder.java | 2 +- .../api/fluids/GTFluidRegistration.java | 2 +- .../api/fluids/store/FluidStorage.java | 90 ++-------------- .../api/fluids/store/FluidStorageImpl.java | 101 ++++++++++++++++++ .../api/fluids/store/FluidStorageKey.java | 19 ++-- .../api/fluids/store/FluidStorageKeys.java | 30 +++++- .../api/unification/material/Material.java | 13 ++- .../materials/FirstDegreeMaterials.java | 2 +- .../material/properties/FluidProperty.java | 85 +++++++++++++-- .../material/MaterialExpansion.java | 2 +- .../material/MaterialPropertyExpansion.java | 18 ++-- .../integration/groovy/MaterialExpansion.java | 2 +- .../groovy/MaterialPropertyExpansion.java | 2 +- 13 files changed, 236 insertions(+), 132 deletions(-) create mode 100644 src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index a7c9d6528ef..31c9caad896 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -390,7 +390,7 @@ private static int convertViscosity(double viscosity) { private void determineName(@Nullable Material material, @Nullable FluidStorageKey key) { if (name != null) return; if (material == null || key == null) throw new IllegalArgumentException("Fluid must have a name"); - name = key.getRegistryNameFor(material.getName()); + name = key.getRegistryNameFor(material); } private void determineTextures(@Nullable Material material, @Nullable FluidStorageKey key, @NotNull String modid) { diff --git a/src/main/java/gregtech/api/fluids/GTFluidRegistration.java b/src/main/java/gregtech/api/fluids/GTFluidRegistration.java index 52409e9f871..8f690c15c4c 100644 --- a/src/main/java/gregtech/api/fluids/GTFluidRegistration.java +++ b/src/main/java/gregtech/api/fluids/GTFluidRegistration.java @@ -82,7 +82,7 @@ public void register() { for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { FluidProperty property = material.getProperty(PropertyKey.FLUID); if (property != null) { - property.getStorage().registerFluids(material); + property.registerFluids(material); } } } diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorage.java b/src/main/java/gregtech/api/fluids/store/FluidStorage.java index fe7505423d0..f939e3b76e2 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorage.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorage.java @@ -1,27 +1,13 @@ package gregtech.api.fluids.store; import gregtech.api.fluids.FluidBuilder; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTLog; import net.minecraftforge.fluids.Fluid; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Comparator; -import java.util.Map; - -public final class FluidStorage { - - private final Map map = new Object2ObjectOpenHashMap<>(); - private Map toRegister = new Object2ObjectOpenHashMap<>(); - - private boolean registered = false; - - public FluidStorage() {} +public interface FluidStorage { /** * Enqueue a fluid for registration @@ -29,81 +15,21 @@ public FluidStorage() {} * @param key the key corresponding with the fluid * @param builder the FluidBuilder to build */ - public void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { - if (registered) { - throw new IllegalStateException("Cannot enqueue a builder after registration"); - } - - if (toRegister.containsKey(key)) { - throw new IllegalArgumentException("FluidStorageKey " + key + " is already queued"); - } - toRegister.put(key, builder); - } + void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder); /** * @param key the key corresponding with the FluidBuilder * @return the fluid builder queued to be registered */ - public @Nullable FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key) { - if (registered) { - throw new IllegalArgumentException("FluidStorage has already been registered"); - } - return toRegister.get(key); - } - - /** - * Register the enqueued fluids - * - * @param material the material the fluid is based off of - */ - @ApiStatus.Internal - public void registerFluids(@NotNull Material material) { - if (registered) { - throw new IllegalStateException("FluidStorage has already been registered"); - } - - // If nothing is queued for registration and nothing is manually stored, - // we need something for the registry to handle this will prevent cases - // of a material having a fluid property but no fluids actually created - // for the material. - if (toRegister.isEmpty() && map.isEmpty()) { - enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); - } - - toRegister.entrySet().stream() - .sorted(Comparator.comparingInt(e -> -e.getKey().getRegistrationPriority())) - .forEach(entry -> { - Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); - if (!storeNoOverwrites(entry.getKey(), fluid)) { - GTLog.logger.error("{} already has an associated fluid for material {}", material); - } - }); - toRegister = null; - registered = true; - } + @Nullable + FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key); /** * @param key the key corresponding with the fluid * @return the fluid associated with the key */ - public @Nullable Fluid get(@NotNull FluidStorageKey key) { - return map.get(key); - } - - /** - * Will do nothing if an existing fluid association would be overwritten. - * - * @param key the key to associate with the fluid - * @param fluid the fluid to associate with the key - * @return if the associations were successfully updated - */ - public boolean storeNoOverwrites(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { - if (map.containsKey(key)) { - return false; - } - store(key, fluid); - return true; - } + @Nullable + Fluid get(@NotNull FluidStorageKey key); /** * Will overwrite existing fluid associations. @@ -111,7 +37,5 @@ public boolean storeNoOverwrites(@NotNull FluidStorageKey key, @NotNull Fluid fl * @param key the key to associate with the fluid * @param fluid the fluid to associate with the key */ - public void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { - map.put(key, fluid); - } + void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid); } diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java b/src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java new file mode 100644 index 00000000000..06911df8deb --- /dev/null +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java @@ -0,0 +1,101 @@ +package gregtech.api.fluids.store; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.unification.material.Material; +import gregtech.api.util.GTLog; + +import net.minecraftforge.fluids.Fluid; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Comparator; +import java.util.Map; + +public final class FluidStorageImpl implements FluidStorage { + + private final Map map = new Object2ObjectOpenHashMap<>(); + private Map toRegister = new Object2ObjectOpenHashMap<>(); + + private boolean registered = false; + + public FluidStorageImpl() {} + + @Override + public void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { + if (registered) { + throw new IllegalStateException("Cannot enqueue a builder after registration"); + } + + if (toRegister.containsKey(key)) { + throw new IllegalArgumentException("FluidStorageKey " + key + " is already queued"); + } + toRegister.put(key, builder); + } + + @Override + public @Nullable FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key) { + if (registered) { + throw new IllegalArgumentException("FluidStorageImpl has already been registered"); + } + return toRegister.get(key); + } + + /** + * Register the enqueued fluids + * + * @param material the material the fluid is based off of + */ + @ApiStatus.Internal + public void registerFluids(@NotNull Material material) { + if (registered) { + throw new IllegalStateException("FluidStorageImpl has already been registered"); + } + + // If nothing is queued for registration and nothing is manually stored, + // we need something for the registry to handle this will prevent cases + // of a material having a fluid property but no fluids actually created + // for the material. + if (toRegister.isEmpty() && map.isEmpty()) { + enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); + } + + toRegister.entrySet().stream() + .sorted(Comparator.comparingInt(e -> -e.getKey().getRegistrationPriority())) + .forEach(entry -> { + Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); + if (!storeNoOverwrites(entry.getKey(), fluid)) { + GTLog.logger.error("{} already has an associated fluid for material {}", material); + } + }); + toRegister = null; + registered = true; + } + + @Override + public @Nullable Fluid get(@NotNull FluidStorageKey key) { + return map.get(key); + } + + /** + * Will do nothing if an existing fluid association would be overwritten. + * + * @param key the key to associate with the fluid + * @param fluid the fluid to associate with the key + * @return if the associations were successfully updated + */ + private boolean storeNoOverwrites(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { + if (map.containsKey(key)) { + return false; + } + store(key, fluid); + return true; + } + + @Override + public void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { + map.put(key, fluid); + } +} diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java index 7b58514aa35..4000c1d5ef9 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.function.Function; -import java.util.function.UnaryOperator; public final class FluidStorageKey { @@ -20,32 +19,32 @@ public final class FluidStorageKey { private final ResourceLocation resourceLocation; private final MaterialIconType iconType; - private final UnaryOperator registryNameOperator; + private final Function registryNameFunction; private final Function translationKeyFunction; private final int hashCode; private final FluidState defaultFluidState; private final int registrationPriority; public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, - @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> registryNameFunction, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction) { - this(resourceLocation, iconType, registryNameOperator, translationKeyFunction, null); + this(resourceLocation, iconType, registryNameFunction, translationKeyFunction, null); } public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, - @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> registryNameFunction, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, @Nullable FluidState defaultFluidState) { - this(resourceLocation, iconType, registryNameOperator, translationKeyFunction, defaultFluidState, 0); + this(resourceLocation, iconType, registryNameFunction, translationKeyFunction, defaultFluidState, 0); } public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, - @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> registryNameFunction, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, @Nullable FluidState defaultFluidState, int registrationPriority) { this.resourceLocation = resourceLocation; this.iconType = iconType; - this.registryNameOperator = registryNameOperator; + this.registryNameFunction = registryNameFunction; this.translationKeyFunction = translationKeyFunction; this.hashCode = resourceLocation.hashCode(); this.defaultFluidState = defaultFluidState; @@ -72,8 +71,8 @@ public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull Mate * @param baseName the base name of the fluid * @return the registry name to use */ - public @NotNull String getRegistryNameFor(@NotNull String baseName) { - return registryNameOperator.apply(baseName); + public @NotNull String getRegistryNameFor(@NotNull Material baseName) { + return registryNameFunction.apply(baseName); } /** diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java index 3b9a6be51e8..515fb605270 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java @@ -1,10 +1,12 @@ package gregtech.api.fluids.store; import gregtech.api.fluids.FluidState; +import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; +import gregtech.api.unification.material.properties.FluidProperty; import gregtech.api.unification.material.properties.PropertyKey; -import java.util.function.UnaryOperator; +import org.jetbrains.annotations.NotNull; import static gregtech.api.util.GTUtility.gregtechId; @@ -12,18 +14,20 @@ public final class FluidStorageKeys { public static final FluidStorageKey LIQUID = new FluidStorageKey(gregtechId("liquid"), MaterialIconType.liquid, - UnaryOperator.identity(), + m -> prefixedRegistryName("liquid.", FluidStorageKeys.LIQUID, m), m -> m.hasProperty(PropertyKey.DUST) ? "gregtech.fluid.liquid_generic" : "gregtech.fluid.generic", FluidState.LIQUID); public static final FluidStorageKey GAS = new FluidStorageKey(gregtechId("gas"), MaterialIconType.gas, - UnaryOperator.identity(), + m -> prefixedRegistryName("gas.", FluidStorageKeys.GAS, m), m -> { if (m.hasProperty(PropertyKey.DUST)) { return "gregtech.fluid.gas_vapor"; } - if (m.isElement()) { + + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (m.isElement() || (property != null && property.getPrimaryKey() != FluidStorageKeys.LIQUID)) { return "gregtech.fluid.gas_generic"; } return "gregtech.fluid.generic"; @@ -32,8 +36,24 @@ public final class FluidStorageKeys { public static final FluidStorageKey PLASMA = new FluidStorageKey(gregtechId("plasma"), MaterialIconType.plasma, - s -> "plasma." + s, m -> "gregtech.fluid.plasma", + m -> "plasma." + m.getName(), + m -> "gregtech.fluid.plasma", FluidState.PLASMA, -1); private FluidStorageKeys() {} + + /** + * @param prefix the prefix string for the registry name + * @param key the key which does not require the prefix + * @param material the material to create a registry name for + * @return the registry name + */ + private static @NotNull String prefixedRegistryName(@NotNull String prefix, @NotNull FluidStorageKey key, + @NotNull Material material) { + FluidProperty property = material.getProperty(PropertyKey.FLUID); + if (property != null && property.getPrimaryKey() != key) { + return prefix + material.getName(); + } + return material.getName(); + } } diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 8a80801af48..18770e5325c 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -209,10 +209,7 @@ public Fluid getFluid() { throw new IllegalArgumentException("Material " + getResourceLocation() + " does not have a Fluid!"); } - FluidStorageKey key = prop.getPrimaryKey(); - Fluid fluid = null; - - if (key != null) fluid = prop.getStorage().get(key); + Fluid fluid = prop.get(prop.getPrimaryKey()); if (fluid != null) return fluid; fluid = getFluid(FluidStorageKeys.LIQUID); @@ -231,7 +228,7 @@ public Fluid getFluid(@NotNull FluidStorageKey key) { throw new IllegalArgumentException("Material " + getResourceLocation() + " does not have a Fluid!"); } - return prop.getStorage().get(key); + return prop.get(key); } /** @@ -522,7 +519,8 @@ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidState state) { public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { properties.ensureSet(PropertyKey.FLUID); FluidProperty property = properties.getProperty(PropertyKey.FLUID); - property.getStorage().enqueueRegistration(key, builder); + property.enqueueRegistration(key, builder); + return this; } @@ -535,7 +533,8 @@ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder public Builder fluid(@NotNull Fluid fluid, @NotNull FluidStorageKey key, @NotNull FluidState state) { properties.ensureSet(PropertyKey.FLUID); FluidProperty property = properties.getProperty(PropertyKey.FLUID); - property.getStorage().store(key, fluid); + property.store(key, fluid); + postProcessors.add( m -> FluidTooltipUtil.registerTooltip(fluid, FluidTooltipUtil.createFluidTooltip(m, fluid, state))); return this; diff --git a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java index c5136fc4a32..9f6c190d6f3 100644 --- a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java @@ -1204,7 +1204,7 @@ public static void register() { .build(); Iron3Chloride = new Material.Builder(411, gregtechId("iron_iii_chloride")) - .fluid() + .liquid() .color(0x060B0B) .flags(DECOMPOSITION_BY_ELECTROLYZING) .components(Iron, 1, Chlorine, 3) diff --git a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java index 80c971fb4f1..d8662ec6bed 100644 --- a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java @@ -1,51 +1,114 @@ package gregtech.api.unification.material.properties; +import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.store.FluidStorage; +import gregtech.api.fluids.store.FluidStorageImpl; import gregtech.api.fluids.store.FluidStorageKey; import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class FluidProperty implements IMaterialProperty { +public class FluidProperty implements IMaterialProperty, FluidStorage { - private final FluidStorage storage = new FluidStorage(); - private @Nullable FluidStorageKey primaryKey = null; + private final FluidStorageImpl storage = new FluidStorageImpl(); + private FluidStorageKey primaryKey = null; private @Nullable Fluid solidifyingFluid = null; public FluidProperty() {} + /** + * Helper constructor which automatically calls {@link #enqueueRegistration(FluidStorageKey, FluidBuilder)} for a + * builder. + *

+ * This is primarily useful for adding FluidProperties to materials after they are registered with a single fluid + * stored. + * + * @param key the fluid storage key to store the builder with + * @param builder the builder to enqueue + */ + public FluidProperty(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { + enqueueRegistration(key, builder); + } + + /** + * Obsolete method, FluidProperty now contains this functionality. + * + * @deprecated {@link FluidStorage} + */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + @Deprecated public @NotNull FluidStorage getStorage() { - return this.storage; + return this; } /** - * @return the FluidStorageKey fluid is stored as primarily + * @see FluidStorageImpl#registerFluids(Material) */ - public @Nullable FluidStorageKey getPrimaryKey() { + @ApiStatus.Internal + public void registerFluids(@NotNull Material material) { + this.storage.registerFluids(material); + } + + @Override + public void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { + storage.enqueueRegistration(key, builder); + if (primaryKey == null) { + primaryKey = key; + } + } + + @Override + public void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { + storage.store(key, fluid); + if (primaryKey == null) { + primaryKey = key; + } + } + + @Override + public @Nullable Fluid get(@NotNull FluidStorageKey key) { + return storage.get(key); + } + + @Override + public @Nullable FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key) { + return storage.getQueuedBuilder(key); + } + + /** + * + * @return the key the fluid is stored with primarily + */ + public @NotNull FluidStorageKey getPrimaryKey() { return primaryKey; } /** * @param primaryKey the key to use primarily */ - public void setPrimaryKey(@Nullable FluidStorageKey primaryKey) { + public void setPrimaryKey(@NotNull FluidStorageKey primaryKey) { this.primaryKey = primaryKey; } @Override - public void verifyProperty(MaterialProperties properties) {} + public void verifyProperty(MaterialProperties properties) { + if (this.primaryKey == null) { + throw new IllegalStateException("FluidProperty cannot be empty"); + } + } /** * @return the Fluid which solidifies into the material. */ - - public Fluid solidifiesFrom() { + public @Nullable Fluid solidifiesFrom() { if (this.solidifyingFluid == null) { - return getStorage().get(FluidStorageKeys.LIQUID); + return storage.get(FluidStorageKeys.LIQUID); } return solidifyingFluid; } diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java index aeef7c2ac07..c0ae3b20efa 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java @@ -60,7 +60,7 @@ public static String getIconSet(Material m) { @ZenGetter public static boolean isGaseous(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); - return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + return prop != null && prop.get(FluidStorageKeys.GAS) != null; } // TODO May need to move this to Material diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java index bf4624282cb..244d99174e1 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java @@ -3,7 +3,6 @@ import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.FluidState; import gregtech.api.fluids.attribute.FluidAttributes; -import gregtech.api.fluids.store.FluidStorage; import gregtech.api.fluids.store.FluidStorageKeys; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.*; @@ -147,7 +146,7 @@ public static void addFluid(Material m) { if (checkFrozen("add a Fluid to a material")) return; if (!m.hasProperty(PropertyKey.FLUID)) { FluidProperty property = new FluidProperty(); - property.getStorage().enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); + property.enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); m.setProperty(PropertyKey.FLUID, property); } } @@ -162,18 +161,17 @@ public static void addFluid(Material m, @Optional String fluidTypeName, @Optiona m.setProperty(PropertyKey.FLUID, property); } - FluidStorage storage = property.getStorage(); FluidBuilder builder = switch (type) { - case LIQUID -> storage.getQueuedBuilder(FluidStorageKeys.LIQUID); - case GAS -> storage.getQueuedBuilder(FluidStorageKeys.GAS); - case PLASMA -> storage.getQueuedBuilder(FluidStorageKeys.PLASMA); + case LIQUID -> property.getQueuedBuilder(FluidStorageKeys.LIQUID); + case GAS -> property.getQueuedBuilder(FluidStorageKeys.GAS); + case PLASMA -> property.getQueuedBuilder(FluidStorageKeys.PLASMA); }; if (builder == null) { builder = new FluidBuilder(); switch (type) { - case LIQUID -> storage.enqueueRegistration(FluidStorageKeys.LIQUID, builder); - case GAS -> storage.enqueueRegistration(FluidStorageKeys.GAS, builder.state(FluidState.GAS)); - case PLASMA -> storage.enqueueRegistration(FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); + case LIQUID -> property.enqueueRegistration(FluidStorageKeys.LIQUID, builder); + case GAS -> property.enqueueRegistration(FluidStorageKeys.GAS, builder.state(FluidState.GAS)); + case PLASMA -> property.enqueueRegistration(FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); } } if (hasBlock) builder.block(); @@ -218,7 +216,7 @@ public static void addPlasma(Material m) { if (checkFrozen("add a Plasma to a material")) return; if (!m.hasProperty(PropertyKey.FLUID)) { FluidProperty property = new FluidProperty(); - property.getStorage().enqueueRegistration(FluidStorageKeys.PLASMA, + property.enqueueRegistration(FluidStorageKeys.PLASMA, new FluidBuilder().state(FluidState.PLASMA)); m.setProperty(PropertyKey.FLUID, property); } diff --git a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java index 70b92dd04d9..6d5f5e7ac2f 100644 --- a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java @@ -53,7 +53,7 @@ public static String getIconSet(Material m) { public static boolean isGaseous(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); - return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + return prop != null && prop.get(FluidStorageKeys.GAS) != null; } /////////////////////////////////// diff --git a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java index 83ceb1b27a7..79cc7c810aa 100644 --- a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java +++ b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java @@ -174,7 +174,7 @@ private static void addFluidInternal(Material m, FluidStorageKey key, FluidBuild property = new FluidProperty(); m.setProperty(PropertyKey.FLUID, property); } - property.getStorage().enqueueRegistration(key, builder); + property.enqueueRegistration(key, builder); } public static void addLiquid(Material m, FluidBuilder builder) { From 6734d8c727e3d239c03e4256710f0a3690a2f7c1 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:57:17 -0400 Subject: [PATCH 144/168] fix failing builds due to Vintagium (#2521) --- dependencies.gradle | 12 ------------ .../render/chunk/passes/BlockRenderPass.java | 11 +++++++++++ .../mods/sodium/client/util/BufferSizeUtil.java | 14 ++++++++++++++ .../mods/sodium/client/util/EnumUtil.java | 12 ++++++++++++ 4 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java create mode 100644 src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java create mode 100644 src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java diff --git a/dependencies.gradle b/dependencies.gradle index e2ef40e1819..588fd821a59 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -57,18 +57,6 @@ dependencies { compileOnly rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 compileOnly rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 - // Special Vintagium Hackery - // Vintagium is currently only distributed as a .zip containing the reobf and -dev jars on Github Actions, which is not ideal - // Using a fake Ivy repo to download it does not work, as nightly.link does not support http HEAD requests, which Gradle wants - mkdir("libs") - // Using Gradle's Ant integration seems to be the least hacky way to download an arbitrary file without a plugin - ant.get(src: "https://nightly.link/Asek3/sodium-1.12/workflows/gradle/12.x%2Fforge/Vintagium.zip", - dest: "libs", - skipexisting: 'true') - ant.unzip(src: "libs/Vintagium.zip", - dest: "libs") - compileOnly(files("libs/vintagium-mc1.12.2-0.1-dev.jar")) - // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. diff --git a/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java b/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java new file mode 100644 index 00000000000..7ac97f9d095 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java @@ -0,0 +1,11 @@ +package me.jellysquid.mods.sodium.client.render.chunk.passes; + +/** + * Adapted and minimized from BlockRenderPass.java + */ +public enum BlockRenderPass { + ; + + public static BlockRenderPass[] VALUES; + public static int COUNT; +} diff --git a/src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java b/src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java new file mode 100644 index 00000000000..dee60c5a9d9 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java @@ -0,0 +1,14 @@ +package me.jellysquid.mods.sodium.client.util; + +import net.minecraft.util.BlockRenderLayer; + +import java.util.HashMap; +import java.util.Map; + +/** + * Adapted and minimized from BufferSizeUtil.java + */ +public class BufferSizeUtil { + + public static final Map BUFFER_SIZES = new HashMap<>(); +} diff --git a/src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java b/src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java new file mode 100644 index 00000000000..da58e286b15 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java @@ -0,0 +1,12 @@ +package me.jellysquid.mods.sodium.client.util; + +import net.minecraft.util.BlockRenderLayer; + +/** + * Adapted and minimized from EnumUtil.java + */ +public class EnumUtil { + + public static BlockRenderLayer[] LAYERS = BlockRenderLayer.values(); + +} From 05036945168aa51f38bc410722665f70c5f50eff Mon Sep 17 00:00:00 2001 From: alongstringofnumbers Date: Fri, 5 Jul 2024 21:10:08 -0700 Subject: [PATCH 145/168] 2.8.9 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 71338bd1ddb..7d848adf4c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion=2.8.8-beta +modVersion=2.8.9-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From fecdfeafb49b9f0fe31f4d8663a21f56cc18dd28 Mon Sep 17 00:00:00 2001 From: M_W_K <31022105+M-W-K@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:03:29 -0600 Subject: [PATCH 146/168] Improvement to DT hatch logic (#2524) (cherry picked from commit 3d944344f8b11f82e159645779aa9826be734ad3) --- .../api/capability/IDistillationTower.java | 22 ++ .../impl/DistillationTowerLogicHandler.java | 199 ++++++++++++++++++ .../MetaTileEntityDistillationTower.java | 127 +++-------- 3 files changed, 254 insertions(+), 94 deletions(-) create mode 100644 src/main/java/gregtech/api/capability/IDistillationTower.java create mode 100644 src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java diff --git a/src/main/java/gregtech/api/capability/IDistillationTower.java b/src/main/java/gregtech/api/capability/IDistillationTower.java new file mode 100644 index 00000000000..e7bf447518b --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDistillationTower.java @@ -0,0 +1,22 @@ +package gregtech.api.capability; + +import gregtech.api.metatileentity.multiblock.IMultiblockPart; + +import net.minecraft.util.math.BlockPos; + +import java.util.List; + +/** + * intended for use in conjunction with {@link gregtech.api.capability.impl.DistillationTowerLogicHandler} + * use with distillation tower type multiblocks + */ +public interface IDistillationTower { + + List getMultiblockParts(); + + BlockPos getPos(); + + void invalidateStructure(); + + boolean allowSameFluidFillForOutputs(); +} diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java new file mode 100644 index 00000000000..e674db66763 --- /dev/null +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -0,0 +1,199 @@ +package gregtech.api.capability.impl; + +import gregtech.api.capability.IDistillationTower; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.util.GTLog; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Allows hatchscan behavior to be used on fluid outputs. Not a child of {@link AbstractRecipeLogic} + * for compatibility with other children. + */ +public class DistillationTowerLogicHandler { + + protected final IDistillationTower tower; + + private int layerCount; + private List orderedFluidOutputs; + private IMultipleTankHandler fluidTanks; + + public DistillationTowerLogicHandler(IDistillationTower tower) { + this.tower = tower; + } + + /** + * Applies fluids to outputs on a sorted one fluid -> one hatch basis + * + * @param fluids the fluids to output. Will be automatically trimmed if there are not enough output hatches. + * @param doFill whether the application should be simulated or not. + * @return whether the fluids were successfully applied to the outputs or not. + */ + public boolean applyFluidToOutputs(List fluids, boolean doFill) { + boolean valid = true; + for (int i = 0; i < Math.min(fluids.size(), this.getOrderedFluidOutputs().size()); i++) { + IFluidHandler handler = this.getOrderedFluidOutputs().get(i); + int accepted = handler.fill(fluids.get(i), doFill); + if (accepted != fluids.get(i).amount) valid = false; + if (!doFill && !valid) break; + } + return valid; + } + + /** + * Called on structure formation to determine the number of layers in the distillation tower.
+ *
+ * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @param structurePattern the structure pattern + */ + public void determineLayerCount(@NotNull BlockPattern structurePattern) { + this.setLayerCount(structurePattern.formedRepetitionCount[1] + 1); + } + + /** + * Called on structure formation to determine the ordered list of fluid handlers in the distillation tower.
+ *
+ * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + */ + public void determineOrderedFluidOutputs() { + // noinspection SimplifyStreamApiCallChains + List fluidExportParts = tower.getMultiblockParts().stream() + .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && + abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && + abilityPart instanceof MetaTileEntityMultiblockPart) + .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) + .collect(Collectors.toList()); + // the fluidExportParts should come sorted in smallest Y first, largest Y last. + List orderedHandlerList = new ObjectArrayList<>(); + List tankList = new ObjectArrayList<>(); + int firstY = tower.getPos().getY() + 1; + int exportIndex = 0; + for (int y = firstY; y < firstY + this.getLayerCount(); y++) { + if (fluidExportParts.size() <= exportIndex) { + orderedHandlerList.add(FakeTank.INSTANCE); + tankList.add(FakeTank.INSTANCE); + continue; + } + MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); + if (part.getPos().getY() == y) { + List hatchTanks = new ObjectArrayList<>(); + // noinspection unchecked + ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); + orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + tankList.addAll(hatchTanks); + exportIndex++; + } else if (part.getPos().getY() > y) { + orderedHandlerList.add(FakeTank.INSTANCE); + tankList.add(FakeTank.INSTANCE); + } else { + GTLog.logger.error( + "The Distillation Tower at {} had a fluid export hatch with an unexpected Y position.", + tower.getPos()); + tower.invalidateStructure(); + this.setOrderedFluidOutputs(new ObjectArrayList<>()); + this.setFluidTanks(new FluidTankList(false)); + } + } + this.setOrderedFluidOutputs(orderedHandlerList); + this.setFluidTanks(new FluidTankList(tower.allowSameFluidFillForOutputs(), tankList)); + } + + /** + * Should be called on structure invalidation. + */ + public void invalidate() { + this.setLayerCount(0); + this.setOrderedFluidOutputs(null); + } + + protected void setLayerCount(int layerCount) { + this.layerCount = layerCount; + } + + public int getLayerCount() { + return layerCount; + } + + protected void setOrderedFluidOutputs(List orderedFluidOutputs) { + this.orderedFluidOutputs = orderedFluidOutputs; + } + + public List getOrderedFluidOutputs() { + return orderedFluidOutputs; + } + + protected void setFluidTanks(IMultipleTankHandler fluidTanks) { + this.fluidTanks = fluidTanks; + } + + public IMultipleTankHandler getFluidTanks() { + return fluidTanks; + } + + // an endless void devouring any fluid sent to it + protected static class FakeTank implements IFluidHandler, IFluidTank { + + protected static final FakeTank INSTANCE = new FakeTank(); + public static final FluidTankInfo FAKE_TANK_INFO = new FluidTankInfo(null, Integer.MAX_VALUE); + public static final IFluidTankProperties FAKE_TANK_PROPERTIES = new FluidTankProperties(null, Integer.MAX_VALUE, + true, false); + public static final IFluidTankProperties[] FAKE_TANK_PROPERTIES_ARRAY = new IFluidTankProperties[] { + FAKE_TANK_PROPERTIES }; + + @Override + public IFluidTankProperties[] getTankProperties() { + return FAKE_TANK_PROPERTIES_ARRAY; + } + + @Override + public FluidStack getFluid() { + return null; + } + + @Override + public int getFluidAmount() { + return 0; + } + + @Override + public int getCapacity() { + return Integer.MAX_VALUE; + } + + @Override + public FluidTankInfo getInfo() { + return FAKE_TANK_INFO; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return resource.amount; + } + + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + return null; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + return null; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 41e1da2ea88..8c8ac6f5407 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -1,11 +1,11 @@ package gregtech.common.metatileentities.multi.electric; +import gregtech.api.capability.IDistillationTower; import gregtech.api.capability.IMultipleTankHandler; -import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.DistillationTowerLogicHandler; import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; @@ -14,7 +14,6 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; @@ -23,7 +22,6 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.state.IBlockState; @@ -33,46 +31,46 @@ import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandlerModifiable; -import com.cleanroommc.modularui.utils.FluidTankHandler; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.Function; -import java.util.stream.Collectors; import static gregtech.api.util.RelativeDirection.*; -public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController { +public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController implements IDistillationTower { - private final boolean useAdvHatchLogic; - - protected int layerCount; - protected List orderedFluidOutputs; + protected DistillationTowerLogicHandler handler; + @SuppressWarnings("unused") // backwards compatibility public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId) { this(metaTileEntityId, false); } public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId, boolean useAdvHatchLogic) { super(metaTileEntityId, RecipeMaps.DISTILLATION_RECIPES); - this.useAdvHatchLogic = useAdvHatchLogic; if (useAdvHatchLogic) { this.recipeMapWorkable = new DistillationTowerRecipeLogic(this); - } + this.handler = new DistillationTowerLogicHandler(this); + } else this.handler = null; } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDistillationTower(metaTileEntityId, this.useAdvHatchLogic); + return new MetaTileEntityDistillationTower(metaTileEntityId, this.handler != null); } + /** + * Used if MultiblockPart Abilities need to be sorted a certain way, like + * Distillation Tower and Assembly Line.
+ *
+ * There will be consequences if this is changed. Make sure to set the logic handler to one with + * a properly overriden {@link DistillationTowerLogicHandler#determineOrderedFluidOutputs()} + */ @Override protected Function multiblockPartSorter() { return RelativeDirection.UP.getSorter(getFrontFacing(), getUpwardsFacing(), isFlipped()); @@ -80,7 +78,9 @@ protected Function multiblockPartSorter() { /** * Whether this multi can be rotated or face upwards.
- * There will be consequences if this returns true. Go override {@link #determineOrderedFluidOutputs()} + *
+ * There will be consequences if this returns true. Make sure to set the logic handler to one with + * a properly overriden {@link DistillationTowerLogicHandler#determineOrderedFluidOutputs()} */ @Override public boolean allowsExtendedFacing() { @@ -106,68 +106,15 @@ protected void addDisplayText(List textList) { @Override protected void formStructure(PatternMatchContext context) { super.formStructure(context); - if (!useAdvHatchLogic || this.structurePattern == null) return; - this.layerCount = determineLayerCount(this.structurePattern); - this.orderedFluidOutputs = determineOrderedFluidOutputs(); - } - - /** - * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. - * - * @param structurePattern the structure pattern - * @return the number of layers that could hold output hatches - */ - protected int determineLayerCount(@NotNull BlockPattern structurePattern) { - return structurePattern.formedRepetitionCount[1] + 1; - } - - /** - * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. - * - * @return the fluid hatches of the multiblock, in order, with null entries for layers that do not have hatches. - */ - protected List determineOrderedFluidOutputs() { - List fluidExportParts = this.getMultiblockParts().stream() - .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && - abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && - abilityPart instanceof MetaTileEntityMultiblockPart) - .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) - .collect(Collectors.toList()); - // the fluidExportParts should come sorted in smallest Y first, largest Y last. - List orderedHandlerList = new ObjectArrayList<>(); - int firstY = this.getPos().getY() + 1; - int exportIndex = 0; - for (int y = firstY; y < firstY + this.layerCount; y++) { - if (fluidExportParts.size() <= exportIndex) { - orderedHandlerList.add(null); - continue; - } - MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); - if (part.getPos().getY() == y) { - List hatchTanks = new ObjectArrayList<>(); - // noinspection unchecked - ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); - if (hatchTanks.size() == 1) - orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); - else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); - exportIndex++; - } else if (part.getPos().getY() > y) { - orderedHandlerList.add(null); - } else { - GTLog.logger.error("The Distillation Tower at " + this.getPos() + - " had a fluid export hatch with an unexpected Y position."); - this.invalidateStructure(); - return new ObjectArrayList<>(); - } - } - return orderedHandlerList; + if (this.handler == null || this.structurePattern == null) return; + handler.determineLayerCount(this.structurePattern); + handler.determineOrderedFluidOutputs(); } @Override public void invalidateStructure() { super.invalidateStructure(); - this.layerCount = 0; - this.orderedFluidOutputs = null; + if (this.handler != null) handler.invalidate(); } @Override @@ -189,7 +136,7 @@ public void invalidateStructure() { } @Override - protected boolean allowSameFluidFillForOutputs() { + public boolean allowSameFluidFillForOutputs() { return false; } @@ -217,7 +164,8 @@ protected ICubeRenderer getFrontOverlay() { @Override public int getFluidOutputLimit() { - return this.layerCount; + if (this.handler != null) return this.handler.getLayerCount(); + else return super.getFluidOutputLimit(); } protected class DistillationTowerRecipeLogic extends MultiblockRecipeLogic { @@ -226,24 +174,10 @@ public DistillationTowerRecipeLogic(MetaTileEntityDistillationTower tileEntity) super(tileEntity); } - protected boolean applyFluidToOutputs(List fluids, boolean doFill) { - boolean valid = true; - for (int i = 0; i < fluids.size(); i++) { - IFluidHandler handler = orderedFluidOutputs.get(i); - // void if no hatch is found on that fluid's layer - // this is considered trimming and thus ignores canVoid - if (handler == null) continue; - int accepted = handler.fill(fluids.get(i), doFill); - if (accepted != fluids.get(i).amount) valid = false; - if (!doFill && !valid) break; - } - return valid; - } - @Override protected void outputRecipeOutputs() { GTTransferUtils.addItemsToItemHandler(getOutputInventory(), false, itemOutputs); - this.applyFluidToOutputs(fluidOutputs, true); + handler.applyFluidToOutputs(fluidOutputs, true); } @Override @@ -268,9 +202,9 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, return false; } - // Perform layerwise fluid checks + // We have already trimmed fluid outputs at this time if (!metaTileEntity.canVoidRecipeFluidOutputs() && - !this.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { + !handler.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { this.isOutputsFull = true; return false; } @@ -282,5 +216,10 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, } return false; } + + @Override + protected IMultipleTankHandler getOutputTank() { + return handler.getFluidTanks(); + } } } From e312c8b84aec11d3ae0f8143c49eb72ab73f6113 Mon Sep 17 00:00:00 2001 From: marisathewitch Date: Sun, 7 Jul 2024 07:03:59 +0400 Subject: [PATCH 147/168] Update ru_RU lang for 2.8.9 (#2523) Co-authored-by: Weblate Co-authored-by: Western01 (cherry picked from commit a706c39e5213ee557fa67c477e27b766606d326c) --- .../resources/assets/gregtech/lang/ru_ru.lang | 88 +++++++++++++++++-- 1 file changed, 80 insertions(+), 8 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/ru_ru.lang b/src/main/resources/assets/gregtech/lang/ru_ru.lang index 5341d2fadb8..2c9e287f40a 100644 --- a/src/main/resources/assets/gregtech/lang/ru_ru.lang +++ b/src/main/resources/assets/gregtech/lang/ru_ru.lang @@ -1130,11 +1130,6 @@ cover.fluid_regulator.title=Настройки регулятора жидкос cover.fluid_regulator.transfer_mode.description=§eПеремещать всё§r — в этом режиме улучшение будет перекачивать столько жидкостей, сколько возможно для ее фильтра./n§eПеремещать точно§r — в этом режиме улучшение будет подавать жидкости порциями, указанными в окне под этой кнопкой. Если количество жидкости меньше размера порции, жидкости не будут перемещены./n§eСохранять точно§r — в этом режиме улучшение будет хранить указанное количество жидкости в инвентаре назначения, при необходимости добавляя дополнительное количество жидкости./ n§7Совет: щелчок Shift умножит увеличение/уменьшение на 10, а щелчок Ctrl умножит на 100. cover.fluid_regulator.supply_exact=Подавать: %s cover.fluid_regulator.keep_exact=Хранить: %s -cover.machine_controller.title=Настройки контроллера механизма -cover.machine_controller.normal=Нормально -cover.machine_controller.inverted=Инверт. -cover.machine_controller.inverted.description=§eНормально§r — в этом режиме для работы улучшения требуется сигнал слабее установленного уровня редстоуна/n§eИнвертировано§r — в этом режиме для работы улучшения требуется сигнал сильнее установленного уровня редстоуна -cover.machine_controller.redstone=Минимальный Редстоун сигнал: %d cover.machine_controller.mode.machine=Контролирует работу механизма cover.machine_controller.mode.cover_up=Контроллер машины (Верх) cover.machine_controller.mode.cover_down=Контроллер машины (Низ) @@ -4754,7 +4749,6 @@ gregtech.machine.me.fluid_export.tooltip=Отправляет жидкости gregtech.machine.me.item_export.tooltip=Отправляет предметы напрямую в ME Сеть. gregtech.machine.me.fluid_import.tooltip=Получает жидкости из сети ME автоматически. gregtech.machine.me.item_import.tooltip=Получает предметы из сети ME автоматически. -gregtech.machine.me.export.tooltip=Имеет бесконечный объем перед подключением в ME Сеть. # Universal tooltips gregtech.universal.tooltip.voltage_in=§aПотребляемое напряжение: §f%,d EU/т (%s§f) @@ -5027,8 +5021,6 @@ gregtech.multiblock.computation.not_enough_computation=§cВНИМАНИЕ:§f gregtech.multiblock.power_substation.stored=Хранит: %s EU gregtech.multiblock.power_substation.capacity=Вместимость: %s EU gregtech.multiblock.power_substation.passive_drain=Пассивный отток: %s EU/t -gregtech.multiblock.power_substation.average_io=Срд. I/O: %s EU/t -gregtech.multiblock.power_substation.average_io_hover=Среднее изменение энергии внутреннего энергобанка подстанции gregtech.multiblock.power_substation.time_to_fill=Время до заполнения: %s gregtech.multiblock.power_substation.time_to_drain=Время до опустошения: %s gregtech.multiblock.power_substation.time_seconds=%s Секунд @@ -5912,3 +5904,83 @@ cover.ore_dictionary_filter.button.case_sensitive.enabled=С учетом рег cover.ore_dictionary_filter.button.match_all.disabled=Любая из записей из Словаря руд cover.ore_dictionary_filter.button.match_all.enabled=Все записи из Словаря руд cover.ore_dictionary_filter.button.case_sensitive.disabled=Без учета регистра +option.gregtech.multi_recipemap=Режимы работы +option.gregtech.primitive_pump=Примитивная помпа +option.gregtech.recipe_logic=Рецепты +option.gregtech.steam_boiler=Паровые котлы +option.gregtech.transformer=Трансформаторы +option.gregtech.workable=Механизмы +item.gt.tool.wire_cutter_lv.name=Электрокусачки (%s §7LV§f) +item.gt.tool.wire_cutter_hv.name=Электрокусачки (%s §6HV§r) +item.gt.tool.wire_cutter_iv.name=Электрокусачки (%s §eIV§r) +cover.voiding.voiding_mode=Режим очистки +tile.powderbarrel.name=Пороховая бочка +entity.ITNT.name=Промышленный динамит +gregtech.machine.me_import_fluid_hatch.configs.tooltip=Держит 16 жидкостей в наличии +gregtech.machine.me.item_export.tooltip.2=Может удерживать в себе бесконечное количество предмета +gregtech.machine.me.fluid_export.tooltip.2=Может удерживать в себе бесконечное количество жидкости +gregtech.machine.me.stocking_auto_pull_disabled=Авто-вытягивание выкл +record.sus=Leonz - Among Us Drip +option.gregtech.diode=Диоды +cover.robotic_arm.exact=§7Пред. +cover.bucket.mode.milli_bucket_exact=Л +option.gregtech.converter=Энерго-преобразователи +option.gregtech.energy=Энергохранилища +option.gregtech.block_lamp=Лампы +option.gregtech.maintenance=Неисправености +option.gregtech.block_ore=Блоки руды +option.gregtech.controllable=Управляемые машины +option.gregtech.multiblock=Мультиблочные структуры +cover.conveyor.distribution.name=Режим распространения +cover.bucket.mode.milli_bucket_rate=Л/с +gregtech.machine.me.stocking_item.tooltip=Извлекает предметы непосредственно из сети ME +gregtech.machine.me_import_item_hatch.configs.tooltip=Держит 16 предметов в наличии +tile.gt_explosive.breaking_tooltip=При обычной добыче взрывается, добудьте с SHIFT, чтобы забрать обратно +gregtech.machine.me.stocking_fluid.tooltip=Извлекает жидкости непосредственно из сети ME +gregtech.machine.me.copy_paste.tooltip=ЛКС с Флешкой для копирования, ПКМ для применения +gregtech.machine.me.import_copy_settings=Настройки сохранены в Флешку +gregtech.machine.me.import_paste_settings=Настройки из Флешки применены +gregtech.machine.me.fluid_import.data_stick.name=§oНастройки ME Накопительного жидкостного люка +gregtech.recipe.dimensions_blocked=Заблокированные измерения: %s +gregtech.gui.item_auto_input.tooltip.enabled=Авто. ввод предметов включен +gregtech.gui.config_slot.set_only=§7Нажмите для §bНастройки§7.§r +gregtech.gui.me_bus.auto_pull_button=Нажмите для переключения авто. вытягивания предметов из МЕ сети +gregtech.multiblock.power_substation.average_out=Сред. выход. EU: %s + +# Mutation +gregtech.mutation.block_of=%s (Блок) +cover.item_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает.\nShift[§6x4§r],Ctrl[§ex16§r],Shift+Ctrl[§ax64§r]\nПравый клик увеличивает кол-во, левый уменьшает.\nShift+ЛКМ для очистки +tile.gt_explosive.lighting_tooltip=Нельзя зажечь с помощью Редстоуна +gregtech.multiblock.power_substation.average_in_hover=Средний приход EU/t в внутреннее хранилище вашей Силовой Подстанции +gregtech.machine.me.stocking_item.tooltip.2=Авто-вытягивание из МЕ сети будет автоматически пополнять первые 16 предметов в МЕ сети, обновляясь раз в 5 сек. +gregtech.machine.me.stocking_fluid.tooltip.2=Авто-вытягивание из МЕ сети будет автоматически пополнять первые 16 слотов жидкости в МЕ сети, обновляясь раз в 5 сек. +gregtech.gui.config_slot.auto_pull_managed=§4Отключено:§7 Управляется Авто-вытягивание +tile.itnt.drops_tooltip=Намного мощнее, чем TNT. Все взорванные блоки выпадают как предметы +gregtech.multiblock.cleanroom.low_tier=Уровень вольтажа слишком низкий, требуется %s или выше! +gregtech.gui.item_auto_input.tooltip.disabled=Авто. ввод предметов выключен +gregtech.gui.me_bus.extra_slot=Доп. Слот/n§7Вложите доп. предмет для рецептов, например Линзы или Формы +gregtech.multiblock.power_substation.average_in=Сред. вход. EU: %s +gregtech.multiblock.power_substation.average_out_hover=Средний отток EU/t из внутреннего хранилище вашей Силовой Подстанции. Включая пассивные потери +gregtech.machine.me.item_import.data_stick.name=§oНастройки ME Накопительного предметного люка +gregtech.machine.me_stocking_item_bus.name=ME Накопительный предметный люк +gregtech.machine.me_stocking_fluid_hatch.name=ME Накопительный жидкостный люк +behaviour.filter_ui_manager=§fПКМ§7 для настроек, §fShift ПКС§7 для очистки +cover.ore_dictionary_filter.match_all=Совпадают все: %s +cover.ore_dictionary_filter.case_sensitive=С учетом регистра: %s +cover.filter.mode.title=Режим фильтра +cover.generic.transfer_mode=Режим передачи +cover.generic.manual_io=Ручной ввод/вывод +cover.generic.io=Режим ввода +cover.pump.mode=Режим помпы +cover.bucket.mode.bucket_rate=кЛ/с +cover.bucket.mode.bucket_exact=кЛ +cover.machine_controller.enable_with_redstone=Включить от Редстоуна +cover.machine_controller.disable_with_redstone=Выключить от Редстоуна +cover.machine_controller.machine_not_controllable=§cМеханизм не управляемый +tile.powderbarrel.drops_tooltip=Немного мощнее, чем TNT. Все взорванные блоки выпадают как предметы +entity.Powderbarrel.name=Пороховая бочка +tile.itnt.name=Промышленный динамит +gregtech.machine.me.stocking_auto_pull_enabled=Авто-вытягивание вкл +cover.machine_controller.this_cover=§cЭто улучшение +cover.machine_controller.cover_not_controllable=§cНет управляемых улучшений +cover.machine_controller.control=Управление: From 263620e57827cfd9273da8f4c0bfc11651787db6 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Sat, 6 Jul 2024 20:08:33 -0700 Subject: [PATCH 148/168] Update Gradle and related files (#2522) Co-authored-by: TechLord22 <37029404+TechLord22@users.noreply.github.com> (cherry picked from commit 52c835ce4177ceb8d78755eca43dca5fb12b09b7) --- gradle/wrapper/gradle-wrapper.jar | Bin 63375 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 19 ++++++++++--------- gradlew.bat | 20 ++++++++++---------- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4cdf41af1ab109bc7f253b2b887023340..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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

NnX)EH+Nua)3Y(c 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≫L+crb^Bz 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 /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -201,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 6689b85beec..7101f8e4676 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From 809a581017d1a83319bd7fc62d554531edf2b94a Mon Sep 17 00:00:00 2001 From: Tian mi <35869948+MCTian-mi@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:51:50 +0800 Subject: [PATCH 149/168] Fix the lighter behaviour (#2526) (cherry picked from commit ae88e46b8387864e27b68401e89f1b767f3372a2) --- .../gregtech/common/items/behaviors/LighterBehaviour.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java index bdff9524d0d..66941091218 100644 --- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java @@ -133,9 +133,11 @@ public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull Wo } BlockPos offset = pos.offset(side); - world.setBlockState(offset, Blocks.FIRE.getDefaultState(), 11); - if (!world.isRemote) { - CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, offset, stack); + if (world.isAirBlock(offset)) { + world.setBlockState(offset, Blocks.FIRE.getDefaultState(), 11); + if (!world.isRemote) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, offset, stack); + } } return EnumActionResult.SUCCESS; } From 27a55e0fed18cadbb55156dfae30e52948121bd4 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 7 Jul 2024 13:33:19 -0500 Subject: [PATCH 150/168] Fix EUt usage of HPCA with custom higher tier Components (#2512) (cherry picked from commit 4c1f89fc921cdbb81545166c9ba2abfd3291944c) --- .../multi/electric/MetaTileEntityHPCA.java | 20 +++++++++--------- .../multiblock/hpca/HPCATest.java | 21 ++++++++++--------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java index 06f8286d8ff..0345a985bd8 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java @@ -167,7 +167,7 @@ protected void updateFormedValid() { } private void consumeEnergy() { - int energyToConsume = hpcaHandler.getCurrentEUt(); + long energyToConsume = hpcaHandler.getCurrentEUt(); boolean hasMaintenance = ConfigHolder.machines.enableMaintenance && hasMaintenanceMechanics(); if (hasMaintenance) { // 10% more energy per maintenance problem @@ -377,7 +377,7 @@ protected ModularUI.Builder createUITemplate(EntityPlayer entityPlayer) { protected void addDisplayText(List textList) { MultiblockDisplayText.builder(textList, isStructureFormed()) .setWorkingStatus(true, hpcaHandler.getAllocatedCWUt() > 0) // transform into two-state system for - // display + // display .setWorkingStatusKeys( "gregtech.multiblock.idling", "gregtech.multiblock.idling", @@ -580,7 +580,7 @@ public static class HPCAGridHandler { // cached gui info // holding these values past the computation clear because GUI is too "late" to read the state in time - private int cachedEUt; + private long cachedEUt; private int cachedCWUt; public HPCAGridHandler(@Nullable MetaTileEntityHPCA controller) { @@ -760,10 +760,10 @@ public int getMaxCWUt() { } /** The current EU/t this HPCA should use, considering passive drain, current computation, etc.. */ - public int getCurrentEUt() { + public long getCurrentEUt() { int maximumCWUt = Math.max(1, getMaxCWUt()); // behavior is no different setting this to 1 if it is 0 - int maximumEUt = getMaxEUt(); - int upkeepEUt = getUpkeepEUt(); + long maximumEUt = getMaxEUt(); + long upkeepEUt = getUpkeepEUt(); if (maximumEUt == upkeepEUt) { return maximumEUt; @@ -775,8 +775,8 @@ public int getCurrentEUt() { } /** The amount of EU/t this HPCA uses just to stay on with 0 output computation. */ - public int getUpkeepEUt() { - int upkeepEUt = 0; + public long getUpkeepEUt() { + long upkeepEUt = 0; for (var component : components) { upkeepEUt += component.getUpkeepEUt(); } @@ -784,8 +784,8 @@ public int getUpkeepEUt() { } /** The maximum EU/t that this HPCA could ever use with the given configuration. */ - public int getMaxEUt() { - int maximumEUt = 0; + public long getMaxEUt() { + long maximumEUt = 0; for (var component : components) { maximumEUt += component.getMaxEUt(); } diff --git a/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java b/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java index 3542313a3f0..fab2e1dbcd5 100644 --- a/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java +++ b/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java @@ -30,16 +30,16 @@ public void Test_Edge_No_Computation() { .coolingAmount(4))); final int maxCWUt = handler.getMaxCWUt(); - final int upkeepEUt = handler.getUpkeepEUt(); - final int maxEUt = handler.getMaxEUt(); + final long upkeepEUt = handler.getUpkeepEUt(); + final long maxEUt = handler.getMaxEUt(); final int maxCoolingDemand = handler.getMaxCoolantDemand(); final int maxCoolingAmount = handler.getMaxCoolingAmount(); int allocated; double temperatureChange; assertThat(maxCWUt, is(0)); - assertThat(upkeepEUt, is(32 * 4)); - assertThat(maxEUt, is(128 * 4)); + assertThat(upkeepEUt, is(32L * 4L)); + assertThat(maxEUt, is(128L * 4L)); assertThat(maxCoolingDemand, is(0)); assertThat(maxCoolingAmount, is(4 * 4)); @@ -69,14 +69,14 @@ public void Test_Edge_Equal_Upkeep_Max_EUt() { .coolingAmount(2))); final int maxCWUt = handler.getMaxCWUt(); - final int upkeepEUt = handler.getUpkeepEUt(); - final int maxEUt = handler.getMaxEUt(); + final long upkeepEUt = handler.getUpkeepEUt(); + final long maxEUt = handler.getMaxEUt(); final int maxCoolingDemand = handler.getMaxCoolingDemand(); final int maxCoolingAmount = handler.getMaxCoolingAmount(); int allocated, requested; double temperatureChange; - final int FIXED_EUT = 32 * 8; + final long FIXED_EUT = 32 * 8; assertThat(maxCWUt, is(4 * 4)); assertThat(upkeepEUt, is(FIXED_EUT)); assertThat(maxEUt, is(FIXED_EUT)); @@ -115,12 +115,13 @@ public void Test_Random() { .EUt(() -> r.nextInt(128)) .coolingAmount(() -> r.nextInt(128)))); - final int maxEUt = handler.getMaxEUt(); - final int upkeepEUt = handler.getUpkeepEUt(); + final long maxEUt = handler.getMaxEUt(); + final long upkeepEUt = handler.getUpkeepEUt(); final int maxCWUt = handler.getMaxCWUt(); final int maxCoolingDemand = handler.getMaxCoolingDemand(); final int maxCoolingAmount = handler.getMaxCoolingAmount(); - int allocated, requested, currentEUt; + int allocated, requested; + long currentEUt; double temperatureChange; // exit, we unit test these edge cases elsewhere From af40e52eb4596af5f3064a389958fe53c167b212 Mon Sep 17 00:00:00 2001 From: Serenibyss <10861407+serenibyss@users.noreply.github.com> Date: Thu, 4 Jul 2024 10:48:23 -0500 Subject: [PATCH 151/168] Update build script version to 1720106721 (#2503) Co-authored-by: ALongStringOfNumbers (cherry picked from commit e4a86bed2118dd3ce2e82151168fc4a6891e320a) --- build.gradle | 268 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 261 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 8ea7b057a37..09eec4b5c3a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1707682661 +//version: 1720106721 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -7,14 +7,24 @@ */ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.gtnewhorizons.retrofuturagradle.MinecraftExtension +import com.gtnewhorizons.retrofuturagradle.mcp.MCPTasks +import com.gtnewhorizons.retrofuturagradle.minecraft.MinecraftTasks import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar +import com.gtnewhorizons.retrofuturagradle.minecraft.RunMinecraftTask +import com.gtnewhorizons.retrofuturagradle.util.Distribution import com.modrinth.minotaur.dependencies.ModDependency import com.modrinth.minotaur.dependencies.VersionDependency +import de.undercouch.gradle.tasks.download.DownloadExtension +import org.apache.commons.io.FileUtils +import org.gradle.api.internal.artifacts.configurations.DefaultUnlockedConfiguration import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.internal.logging.text.StyledTextOutputFactory import org.jetbrains.gradle.ext.Gradle +import javax.inject.Inject + import static org.gradle.internal.logging.text.StyledTextOutput.Style plugins { @@ -23,9 +33,9 @@ plugins { id 'base' id 'eclipse' id 'maven-publish' - id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.33' - id 'net.darkhax.curseforgegradle' version '1.1.18' apply false + id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.8' + id 'com.gtnewhorizons.retrofuturagradle' version '1.4.0' + id 'net.darkhax.curseforgegradle' version '1.1.24' apply false id 'com.modrinth.minotaur' version '2.8.7' apply false id 'com.diffplug.spotless' version '6.13.0' apply false id 'com.palantir.git-version' version '3.0.0' apply false @@ -33,6 +43,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false + id 'de.undercouch.download' version '5.6.0' apply false } def out = services.get(StyledTextOutputFactory).create('an-output') @@ -58,6 +69,8 @@ propertyDefaultIfUnset("includeMCVersionJar", false) propertyDefaultIfUnset("autoUpdateBuildScript", false) propertyDefaultIfUnset("modArchivesBaseName", project.modId) propertyDefaultIfUnsetWithEnvVar("developmentEnvironmentUserName", "Developer", "DEV_USERNAME") +propertyDefaultIfUnset("additionalJavaArguments", "") +propertyDefaultIfUnset("enableJava17RunTasks", false) propertyDefaultIfUnset("generateGradleTokenClass", "") propertyDefaultIfUnset("gradleTokenModId", "") propertyDefaultIfUnset("gradleTokenModName", "") @@ -65,8 +78,10 @@ propertyDefaultIfUnset("gradleTokenVersion", "") propertyDefaultIfUnset("useSrcApiPath", false) propertyDefaultIfUnset("includeWellKnownRepositories", true) propertyDefaultIfUnset("includeCommonDevEnvMods", true) +propertyDefaultIfUnset("stripForgeRequirements", false) propertyDefaultIfUnset("noPublishedSources", false) propertyDefaultIfUnset("forceEnableMixins", false) +propertyDefaultIfUnset("mixinConfigRefmap", "mixins.${project.modId}.refmap.json") propertyDefaultIfUnsetWithEnvVar("enableCoreModDebug", false, "CORE_MOD_DEBUG") propertyDefaultIfUnset("generateMixinConfig", true) propertyDefaultIfUnset("usesShadowedDependencies", false) @@ -107,7 +122,7 @@ if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists( if (apiPackage) { final String endApiPath = modGroupPath + '/' + apiPackagePath - if (useSrcApiPath) { + if (useSrcApiPath.toBoolean()) { targetPackageJava = 'src/api/java/' + endApiPath targetPackageScala = 'src/api/scala/' + endApiPath targetPackageKotlin = 'src/api/kotlin/' + endApiPath @@ -369,6 +384,14 @@ minecraft { '-Dlegacy.debugClassLoadingSave=true' ]) } + + if (additionalJavaArguments.size() != 0) { + extraRunJvmArguments.addAll(additionalJavaArguments.split(';')) + } + + if (enableJava17RunTasks.toBoolean()) { + lwjgl3Version = "3.3.2" + } } if (coreModClass) { @@ -504,7 +527,7 @@ dependencies { // should use 2.8.6 but 2.8.9+ has a vulnerability fix annotationProcessor 'com.google.code.gson:gson:2.8.9' - mixinProviderSpec = modUtils.enableMixins(mixinProviderSpec, "mixins.${modId}.refmap.json") + mixinProviderSpec = modUtils.enableMixins(mixinProviderSpec, mixinConfigRefmap) api (mixinProviderSpec) { transitive = false } @@ -546,6 +569,10 @@ dependencies { transitive = false } + if ((usesMixins.toBoolean() || forceEnableMixins.toBoolean()) && stripForgeRequirements.toBoolean()) { + runtimeOnlyNonPublishable 'com.cleanroommc:strip-latest-forge-requirements:1.0' + } + if (includeCommonDevEnvMods.toBoolean()) { if (!(modId.equals('jei'))) { implementation 'mezz.jei:jei_1.12.2:4.16.1.302' @@ -679,7 +706,6 @@ tasks.register('generateAssets') { if (usesMixins.toBoolean() && generateMixinConfig.toBoolean()) { def mixinConfigFile = getFile("src/main/resources/mixins.${modId}.json") if (!mixinConfigFile.exists()) { - def mixinConfigRefmap = "mixins.${modId}.refmap.json" mixinConfigFile.text = """{ "package": "${modGroup}.${mixinsPackage}", @@ -820,6 +846,218 @@ def getManifestAttributes() { } +// LWJGL3ify setup +if (enableJava17RunTasks.toBoolean()) { + + apply plugin: 'de.undercouch.download' + + ext.java17Toolchain = (JavaToolchainSpec spec) -> { + spec.languageVersion.set(JavaLanguageVersion.of(17)) + spec.vendor.set(JvmVendorSpec.matching("jetbrains")) + } + ext.java21Toolchain = (JavaToolchainSpec spec) -> { + spec.languageVersion.set(JavaLanguageVersion.of(21)) + spec.vendor.set(JvmVendorSpec.matching("jetbrains")) + } + + ext.java17DependenciesCfg = (DefaultUnlockedConfiguration) configurations.create("java17Dependencies") { + extendsFrom(configurations.getByName("runtimeClasspath")) // Ensure consistent transitive dependency resolution + canBeConsumed = false + } + ext.java17PatchDependenciesCfg = (DefaultUnlockedConfiguration) configurations.create("java17PatchDependencies") { + canBeConsumed = false + } + + dependencies { + if (modId != 'lwjgl3ify') { + java17Dependencies("io.github.twilightflower:lwjgl3ify:1.0.0") + } + java17PatchDependencies("io.github.twilightflower:lwjgl3ify:1.0.0:forgePatches") { + transitive = false + } + } + + ext.java17JvmArgs = [ + "-Dfile.encoding=UTF-8", + "-Djava.system.class.loader=com.gtnewhorizons.retrofuturabootstrap.RfbSystemClassLoader", + "-Djava.security.manager=allow", + "--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED", + "--add-opens", "java.base/java.net=ALL-UNNAMED", + "--add-opens", "java.base/java.nio=ALL-UNNAMED", + "--add-opens", "java.base/java.io=ALL-UNNAMED", + "--add-opens", "java.base/java.lang=ALL-UNNAMED", + "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", + "--add-opens", "java.base/java.text=ALL-UNNAMED", + "--add-opens", "java.base/java.util=ALL-UNNAMED", + "--add-opens", "java.base/jdk.internal.reflect=ALL-UNNAMED", + "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", + "--add-opens", "jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming", + "--add-opens", "java.desktop/sun.awt=ALL-UNNAMED", + "--add-opens", "java.desktop/sun.awt.image=ALL-UNNAMED", + "--add-opens", "java.desktop/com.sun.imageio.plugins.png=ALL-UNNAMED", + "--add-opens", "jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED", + "--add-opens", "java.sql.rowset/javax.sql.rowset.serial=ALL-UNNAMED" + ] + + ext.hotswapJvmArgs = [ + // DCEVM advanced hot reload + "-XX:+AllowEnhancedClassRedefinition", + "-XX:HotswapAgent=fatjar" + ] + + ext.setupHotswapAgent17 = tasks.register("setupHotswapAgent17", SetupHotswapAgentTask, t -> { + t.setTargetForToolchain(java17Toolchain) + }) + + ext.setupHotswapAgent21 = tasks.register("setupHotswapAgent21", SetupHotswapAgentTask, t -> { + t.setTargetForToolchain(java21Toolchain) + }) + + def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient") + runClient17Task.configure { + dependsOn(setupHotswapAgent17) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain) + } + + def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer") + runServer17Task.configure { + dependsOn(setupHotswapAgent17) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain) + } + + def runClient21Task = tasks.register("runClient21", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient") + runClient21Task.configure { + dependsOn(setupHotswapAgent21) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java21Toolchain) + } + + def runServer21Task = tasks.register("runServer21", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer") + runServer21Task.configure { + dependsOn(setupHotswapAgent21) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java21Toolchain) + } +} + +abstract class RunHotswappableMinecraftTask extends RunMinecraftTask { + + // IntelliJ doesn't seem to allow pre-set commandline arguments, so we also support an env variable + private boolean enableHotswap = Boolean.valueOf(System.getenv("HOTSWAP")) + + public final Distribution side + public final String superTask + + @Input + boolean getEnableHotswap() { + return enableHotswap + } + + @Option(option = "hotswap", description = "Enables HotSwapAgent for enhanced class reloading under a debugger") + boolean setEnableHotswap(boolean enable) { + enableHotswap = enable + } + + @Inject + RunHotswappableMinecraftTask(Distribution side, String superTask, org.gradle.api.invocation.Gradle gradle) { + super(side, gradle) + + this.side = side + this.superTask = superTask + setGroup("Modded Minecraft") + setDescription("Runs the modded " + side.name().toLowerCase(Locale.ROOT) + " using modern Java and lwjgl3ify") + this.getLwjglVersion().set(3) + } + + void setup(Project project) { + final MinecraftExtension minecraft = project.getExtensions().getByType(MinecraftExtension.class) + final MCPTasks mcpTasks = project.getExtensions().getByType(MCPTasks.class) + final MinecraftTasks mcTasks = project.getExtensions().getByType(MinecraftTasks.class) + + this.getExtraJvmArgs().addAll((List) project.property("java17JvmArgs")) + if (getEnableHotswap()) { + this.getExtraJvmArgs().addAll((List) project.property("hotswapJvmArgs")) + } + + this.classpath(project.property("java17PatchDependenciesCfg")) + this.classpath(mcpTasks.getTaskPackageMcLauncher()) + this.classpath(mcpTasks.getTaskPackagePatchedMc()) + this.classpath(mcpTasks.getPatchedConfiguration()) + this.classpath(project.getTasks().named("jar")) + this.classpath(project.property("java17DependenciesCfg")) + + super.setup(project) + + dependsOn( + mcpTasks.getLauncherSources().getClassesTaskName(), + mcTasks.getTaskDownloadVanillaAssets(), + mcpTasks.getTaskPackagePatchedMc(), + "jar" + ) + + getMainClass().set((side == Distribution.CLIENT) ? "GradleStart" : "GradleStartServer") + getUsername().set(minecraft.getUsername()) + getUserUUID().set(minecraft.getUserUUID()) + if (side == Distribution.DEDICATED_SERVER) { + getExtraArgs().add("nogui") + } + + systemProperty("gradlestart.bouncerClient", "com.gtnewhorizons.retrofuturabootstrap.Main") + systemProperty("gradlestart.bouncerServer", "com.gtnewhorizons.retrofuturabootstrap.Main") + + if (project.usesMixins.toBoolean()) { + this.extraJvmArgs.addAll(project.provider(() -> { + def mixinCfg = project.configurations.detachedConfiguration(project.dependencies.create(project.mixinProviderSpec)) + mixinCfg.canBeConsumed = false + mixinCfg.canBeResolved = true + mixinCfg.transitive = false + enableHotswap ? ["-javaagent:" + mixinCfg.singleFile.absolutePath] : [] + })) + } + } +} + +abstract class SetupHotswapAgentTask extends DefaultTask { + + @OutputFile + abstract RegularFileProperty getTargetFile() + + void setTargetForToolchain(Action spec) { + getTargetFile().set(project.javaToolchains.launcherFor(spec).map { + it.metadata.installationPath.file("lib/hotswap/hotswap-agent.jar") + }) + } + + @Inject + SetupHotswapAgentTask() { + setGroup("GT Buildscript") + setDescription("Installs a recent version of HotSwapAgent into the Java runtime directory") + onlyIf("Run only if not already installed", t -> !((SetupHotswapAgentTask) t).getTargetFile().getAsFile().get().exists()) + } + + @TaskAction + void installHSA() { + final String url = 'https://github.com/HotswapProjects/HotswapAgent/releases/download/1.4.2-SNAPSHOT/hotswap-agent-1.4.2-SNAPSHOT.jar' + final File target = getTargetFile().getAsFile().get() + final File parent = target.getParentFile() + FileUtils.forceMkdir(parent) + final DownloadExtension download = getProject().getExtensions().findByType(DownloadExtension.class) + download.run(ds -> { + try { + ds.src(url) + } catch (MalformedURLException e) { + throw new RuntimeException(e) + } + ds.dest(target) + ds.overwrite(false) + ds.tempAndMove(true) + }) + } +} + + // IDE Configuration eclipse { @@ -844,9 +1082,25 @@ idea { '2. Run Client'(Gradle) { taskNames = ['runClient'] } + if (enableJava17RunTasks.toBoolean()) { + '2a. Run Client (Java 17)'(Gradle) { + taskNames = ['runClient17'] + } + '2b. Run Client (Java 21)'(Gradle) { + taskNames = ['runClient21'] + } + } '3. Run Server'(Gradle) { taskNames = ['runServer'] } + if (enableJava17RunTasks.toBoolean()) { + '3a. Run Server (Java 17)'(Gradle) { + taskNames = ['runServer17'] + } + '3b. Run Server (Java 21)'(Gradle) { + taskNames = ['runServer21'] + } + } '4. Run Obfuscated Client'(Gradle) { taskNames = ['runObfClient'] } From 7d5337d751a498638ffacb1b8e3f0c992d8c2c79 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:42:25 -0400 Subject: [PATCH 152/168] bump GRS and CT versions in gradle (#2528) (cherry picked from commit f149a18d40464d1bb9d82d385aa4efd336f8323a) --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 588fd821a59..4ab055c1f2c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,8 +41,8 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.4.3") { transitive = false } - api("com.cleanroommc:groovyscript:1.1.0") { transitive = false } - api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.698") + api("com.cleanroommc:groovyscript:1.1.1") { transitive = false } + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") api("appeng:ae2-uel:v0.56.4") { transitive = false } api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 From 135982d50840e29b6a534f468783b290825c1dfb Mon Sep 17 00:00:00 2001 From: Ko_no <90126004+MrKono@users.noreply.github.com> Date: Tue, 9 Jul 2024 08:47:09 +0900 Subject: [PATCH 153/168] Update and Fix ja_jp.lang for 2.8.10 (#2534) --- .../resources/assets/gregtech/lang/ja_jp.lang | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/resources/assets/gregtech/lang/ja_jp.lang b/src/main/resources/assets/gregtech/lang/ja_jp.lang index b1564d9161a..40f8e768c95 100644 --- a/src/main/resources/assets/gregtech/lang/ja_jp.lang +++ b/src/main/resources/assets/gregtech/lang/ja_jp.lang @@ -1,7 +1,7 @@ # Japanese translate by MrKo_no & GTModpackTeam # 日本語ローカライズ担当: MrKo_no & GTModpackTeam -# Corresponding Version: 2.8.8 - beta -# 対応バージョン: 2.8.8 - beta +# Corresponding Version: 2.8.10 - beta +# 対応バージョン: 2.8.10 - beta death.attack.heat=%s は熱さを感じなくなった。 death.attack.frost=%s のふとんがふっとんだ。 @@ -552,7 +552,7 @@ metaitem.tool.datamodule.tooltip=とても複雑なデータの保管に/n§cデ metaitem.circuit.integrated.name=プログラム回路 metaitem.circuit.integrated.tooltip=使うと設定画面を開く/n/nプログラム回路スロットを持つ機械に/nシフト右クリックをすると/nこの回路の番号に設定される/n metaitem.circuit.integrated.gui=プログラム回路設定 -metaitem.circuit.integrated.jei_description=JEIでは設定した番号のレシピのみが表示されます。/n番号はプログラム回路の一覧タブで選択できます。 +metaitem.circuit.integrated.jei_description=JEIでは設定した番号のレシピのみが表示されます。\n番号はプログラム回路の一覧タブで選択できます。 item.glass.lens=白いガラスレンズ metaitem.glass_lens.orange.name=橙色のガラスレンズ @@ -1327,6 +1327,11 @@ cover.fluid_regulator.transfer_mode.description=§eすべて移動§r - この cover.fluid_regulator.supply_exact=供給モード: %s cover.fluid_regulator.keep_exact=保持モード: %s +cover.machine_controller.title=機械制御設定 +cover.machine_controller.normal=通常 +cover.machine_controller.inverted=反転 +cover.machine_controller.inverted.description=§e通常§r - このモードは、設定した信号強度よりも弱い信号が入力されている時に機械が動作するようになります。/n§e反転§r - このモードは、設定した信号強度よりも強い信号が入力されている時に機械が動作するようになります。 +cover.machine_controller.redstone=最低レッドストーン信号強度: %,d cover.machine_controller.mode.machine=機械制御 cover.machine_controller.mode.cover_up=上面カバー制御 cover.machine_controller.mode.cover_down=下面カバー制御 @@ -1334,12 +1339,6 @@ cover.machine_controller.mode.cover_south=南面カバー制御 cover.machine_controller.mode.cover_north=北面カバー制御 cover.machine_controller.mode.cover_east=東面カバー制御 cover.machine_controller.mode.cover_west=西面カバー制御 -cover.machine_controller.this_cover=§cこのカバー -cover.machine_controller.cover_not_controllable=§c制御可能なカバーがない -cover.machine_controller.machine_not_controllable=§c機械が制御可能でない -cover.machine_controller.control=制御対象: -cover.machine_controller.enable_with_redstone=赤石信号で動作 -cover.machine_controller.disable_with_redstone=赤石信号で停止 cover.ender_fluid_link.title=液体エンダーリンク cover.ender_fluid_link.iomode.enabled=I/O 有効 @@ -5429,7 +5428,7 @@ gregtech.gui.item_auto_output.tooltip.disabled=アイテム自動搬出を有効 gregtech.gui.item_auto_collapse.tooltip.enabled=アイテムの整頓を有効化 (現在は無効) gregtech.gui.item_auto_collapse.tooltip.disabled=アイテムの整頓を無効化 (現在は有効) gregtech.gui.charger_slot.tooltip=§f充電スロット§r/n%s§7バッテリーからエネルギーを吸い取る。§r/n%s§7の電動ツールとバッテリーを充電できる。 -gregtech.gui.configurator_slot.tooltip=§fプログラム回路スロット§r\n§a設定番号: §f%d§7\n\n§7右/左クリック/スクロールで値を変更する。\n§7シフト左クリックで選択画面を表示。\n§7シフト右クリックでやり直し。 +gregtech.gui.configurator_slot.tooltip=§fプログラム回路スロット§r/n§a設定番号: §f%d§7/n/n§7右/左クリック/スクロールで値を変更する。/n§7シフト右クリックでやり直し。 gregtech.gui.configurator_slot.no_value=なし gregtech.gui.configurator_slot.unavailable.tooltip=プログラム回路スロットは使いません gregtech.gui.fluid_lock.tooltip.enabled=液体ロックを無効化 (現在は有効) @@ -6279,3 +6278,6 @@ gregtech.scanner.forestry.larvae=§o解析済みの幼虫 gregtech.scanner.forestry.serum=§o解析済みの漿液 gregtech.scanner.forestry.caterpillar=§o解析済みの幼虫 gregtech.scanner.forestry.pollen=§o解析済みの花粉 + +# Mutation +gregtech.mutation.block_of=%sブロック From 071a3dc57348addec33fc0d5f3cf36bfaaadb894 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:44:27 -0700 Subject: [PATCH 154/168] Fix Miner Pipe Deleting TileEntities (#2529) (cherry picked from commit dd6f3e3a247548daa6d6615683744f79feb4431a) --- .../java/gregtech/api/capability/impl/miner/MinerLogic.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java b/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java index 5b1ca454f3d..3439aca4a57 100644 --- a/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java +++ b/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java @@ -157,8 +157,10 @@ public void performMining() { // drill a hole beneath the miner and extend the pipe downwards by one WorldServer world = (WorldServer) metaTileEntity.getWorld(); if (mineY.get() < pipeY.get()) { - world.destroyBlock( - new BlockPos(metaTileEntity.getPos().getX(), pipeY.get(), metaTileEntity.getPos().getZ()), false); + var pipePos = new BlockPos(metaTileEntity.getPos().getX(), pipeY.get(), metaTileEntity.getPos().getZ()); + if (world.getTileEntity(pipePos) == null && + world.getBlockState(pipePos).getBlockHardness(world, pipePos) >= 0) + world.destroyBlock(pipePos, false); pipeY.decrementAndGet(); incrementPipeLength(); } From 950fcd894eefb4a83cb46cd256bfe2150d9a30ee Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:46:47 -0400 Subject: [PATCH 155/168] Make drums no longer require a Material (#2527) (cherry picked from commit 69d4e4a793bab4c65ce45a25f9f0b5a1563a9592) --- .../storage/MetaTileEntityDrum.java | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index 7a5ef5b4d38..2292338425f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -9,7 +9,6 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.ModHandler; import gregtech.api.unification.material.Material; -import gregtech.api.unification.material.properties.FluidPipeProperties; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; @@ -54,26 +53,59 @@ public class MetaTileEntityDrum extends MetaTileEntity { + private final IPropertyFluidFilter fluidFilter; + private final boolean isWood; + private final int color; private final int tankSize; - private final Material material; + private FilteredFluidHandler fluidTank; private boolean isAutoOutput = false; - public MetaTileEntityDrum(ResourceLocation metaTileEntityId, Material material, int tankSize) { + /** + * @param metaTileEntityId the id for the MTE + * @param material the material the drum is made of, must have + * {@link gregtech.api.unification.material.properties.FluidProperty}. + * @param tankSize the size of the storage tank + */ + public MetaTileEntityDrum(ResourceLocation metaTileEntityId, @NotNull Material material, int tankSize) { super(metaTileEntityId); + IPropertyFluidFilter filter = material.getProperty(PropertyKey.FLUID_PIPE); + if (filter == null) { + throw new IllegalArgumentException("Material " + material + " requires FluidPipeProperty for Drums"); + } + this.fluidFilter = filter; + this.isWood = ModHandler.isMaterialWood(material); + this.color = material.getMaterialRGB(); + this.tankSize = tankSize; + initializeInventory(); + } + + /** + * + * @param metaTileEntityId the id for the MTE + * @param fluidFilter the filter for which fluids can be stored + * @param isWood if the drum is made of wood + * @param color the color of the drum in RGB format + * @param tankSize the size of the storage tank + */ + public MetaTileEntityDrum(ResourceLocation metaTileEntityId, @NotNull IPropertyFluidFilter fluidFilter, + boolean isWood, int color, int tankSize) { + super(metaTileEntityId); + this.fluidFilter = fluidFilter; + this.isWood = isWood; + this.color = color; this.tankSize = tankSize; - this.material = material; initializeInventory(); } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDrum(metaTileEntityId, material, tankSize); + return new MetaTileEntityDrum(metaTileEntityId, fluidFilter, isWood, color, tankSize); } @Override public String getHarvestTool() { - return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; + return isWood ? ToolClasses.AXE : ToolClasses.WRENCH; } @Override @@ -83,14 +115,14 @@ public boolean hasFrontFacing() { @Override protected void initializeInventory() { - if (this.material == null) return; // call before field initialization, should be called later with fields set - super.initializeInventory(); - IPropertyFluidFilter filter = this.material.getProperty(PropertyKey.FLUID_PIPE); - if (filter == null) { - throw new IllegalArgumentException( - String.format("Material %s requires FluidPipeProperty for Drums", material)); + // call before field initialization, should be called later with fields set + if (this.fluidFilter == null) { + return; } - this.fluidInventory = this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(filter); + + super.initializeInventory(); + this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(this.fluidFilter); + this.fluidInventory = this.fluidTank; } @Override @@ -203,27 +235,26 @@ private void toggleOutput() { @Override @SideOnly(Side.CLIENT) public Pair getParticleTexture() { - if (ModHandler.isMaterialWood(material)) { + if (isWood) { return Pair.of(Textures.WOODEN_DRUM.getParticleTexture(), getPaintingColorForRendering()); } else { - int color = ColourRGBA.multiply( - GTUtility.convertRGBtoOpaqueRGBA_CL(material.getMaterialRGB()), - GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering())); - color = GTUtility.convertOpaqueRGBA_CLtoRGB(color); + int color = GTUtility.convertOpaqueRGBA_CLtoRGB(ColourRGBA.multiply( + GTUtility.convertRGBtoOpaqueRGBA_CL(this.color), + GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); return Pair.of(Textures.DRUM.getParticleTexture(), color); } } @Override public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { - if (ModHandler.isMaterialWood(material)) { + if (isWood) { ColourMultiplier multiplier = new ColourMultiplier( GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering())); Textures.WOODEN_DRUM.render(renderState, translation, ArrayUtils.add(pipeline, multiplier), getFrontFacing()); } else { ColourMultiplier multiplier = new ColourMultiplier( - ColourRGBA.multiply(GTUtility.convertRGBtoOpaqueRGBA_CL(material.getMaterialRGB()), + ColourRGBA.multiply(GTUtility.convertRGBtoOpaqueRGBA_CL(this.color), GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); Textures.DRUM.render(renderState, translation, ArrayUtils.add(pipeline, multiplier), getFrontFacing()); Textures.DRUM_OVERLAY.render(renderState, translation, pipeline); @@ -243,8 +274,7 @@ public int getDefaultPaintingColor() { @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { tooltip.add(I18n.format("gregtech.universal.tooltip.fluid_storage_capacity", tankSize)); - FluidPipeProperties pipeProperties = material.getProperty(PropertyKey.FLUID_PIPE); - pipeProperties.appendTooltips(tooltip, true, true); + this.fluidFilter.appendTooltips(tooltip, true, true); if (TooltipHelper.isShiftDown()) { tooltip.add(I18n.format("gregtech.tool_action.screwdriver.access_covers")); From 8f485c1d0e286f1b9f733e559cf6bb12f7cccbc5 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:47:24 -0400 Subject: [PATCH 156/168] fix crash with Forestry integration (#2531) (cherry picked from commit 7799009f8b47bd1bdefd1f11fe3b8c81bf15ef7e) --- .../api/unification/OreDictUnifier.java | 9 ++++++-- .../mutation/MaterialMutationCondition.java | 22 +++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/unification/OreDictUnifier.java b/src/main/java/gregtech/api/unification/OreDictUnifier.java index a945fe5b4f5..aeaf123cdb2 100644 --- a/src/main/java/gregtech/api/unification/OreDictUnifier.java +++ b/src/main/java/gregtech/api/unification/OreDictUnifier.java @@ -217,8 +217,13 @@ public static boolean hasOreDictionary(@NotNull ItemStack itemStack, @NotNull St return wildcardNames != null && wildcardNames != names && wildcardNames.contains(oreDictName); } - public static List getAllWithOreDictionaryName(String oreDictionaryName) { - return oreDictNameStacks.get(oreDictionaryName).stream() + public static @NotNull List<@NotNull ItemStack> getAllWithOreDictionaryName(@NotNull String oreDictionaryName) { + var stacks = oreDictNameStacks.get(oreDictionaryName); + if (stacks == null) { + return Collections.emptyList(); + } + + return stacks.stream() .map(ItemStack::copy) .collect(Collectors.toList()); } diff --git a/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java index a4ea54cdf23..c063f0fbed8 100644 --- a/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java +++ b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java @@ -2,6 +2,8 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.LocalizationUtils; import net.minecraft.block.Block; @@ -19,22 +21,21 @@ import forestry.api.genetics.IGenome; import forestry.api.genetics.IMutationCondition; import forestry.core.tiles.TileUtil; +import org.jetbrains.annotations.NotNull; import java.util.HashSet; import java.util.Set; -import static org.apache.commons.lang3.StringUtils.capitalize; - public class MaterialMutationCondition implements IMutationCondition { - private final Set acceptedBlocks = new HashSet(); + private final Set acceptedBlocks = new HashSet<>(); private final String displayName; - public MaterialMutationCondition(Material material) { + public MaterialMutationCondition(@NotNull Material material) { this.displayName = LocalizationUtils.format("gregtech.mutation.block_of", material.getLocalizedName()); - String oredictName = "block" + capitalize(material.getName()); + String oreDictName = new UnificationEntry(OrePrefix.block, material).toString(); - for (ItemStack ore : OreDictUnifier.getAllWithOreDictionaryName(oredictName)) { + for (ItemStack ore : OreDictUnifier.getAllWithOreDictionaryName(oreDictName)) { if (!ore.isEmpty()) { Item oreItem = ore.getItem(); Block oreBlock = Block.getBlockFromItem(oreItem); @@ -45,8 +46,10 @@ public MaterialMutationCondition(Material material) { } } - public float getChance(World world, BlockPos pos, IAllele allele0, IAllele allele1, IGenome genome0, - IGenome genome1, IClimateProvider climate) { + @Override + public float getChance(@NotNull World world, @NotNull BlockPos pos, @NotNull IAllele allele0, + @NotNull IAllele allele1, @NotNull IGenome genome0, + @NotNull IGenome genome1, @NotNull IClimateProvider climate) { TileEntity tile; do { pos = pos.down(); @@ -57,7 +60,8 @@ public float getChance(World world, BlockPos pos, IAllele allele0, IAllele allel return this.acceptedBlocks.contains(blockState) ? 1.0F : 0.0F; } - public String getDescription() { + @Override + public @NotNull String getDescription() { return LocalizationUtils.format("for.mutation.condition.resource", this.displayName); } } From 9fe140febe8747bbe2f06dfd570421331ec06f4b Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+techlord22@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:15:03 -0400 Subject: [PATCH 157/168] 2.8.10 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7d848adf4c1..878e4535964 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion=2.8.9-beta +modVersion=2.8.10-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true From bc251e41c756023b22687304bfda5552a77b0b76 Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sun, 8 Dec 2024 14:55:00 +0000 Subject: [PATCH 158/168] Added Avaritia Cosmic Render for MetaItems --- dependencies.gradle | 5 + src/main/java/gregtech/GregTechMod.java | 4 + .../gregtech/api/items/metaitem/MetaItem.java | 201 +++++++++++++++++- .../renderer/item/CosmicItemRenderer.java | 190 +++++++++++++++++ .../java/gregtech/common/items/MetaItem1.java | 2 +- .../textures/items/cosmic/halo/halo.png | Bin 0 -> 3450 bytes .../textures/items/cosmic/halo/halo_noise.png | Bin 0 -> 31598 bytes .../items/cosmic/halo/halo_noise.png.mcmeta | 5 + .../textures/items/cosmic/mask/assembly.png | Bin 0 -> 151 bytes .../textures/items/cosmic/mask/board.png | Bin 0 -> 167 bytes .../items/cosmic/mask/circuit_board.png | Bin 0 -> 198 bytes .../textures/items/cosmic/mask/computer.png | Bin 0 -> 255 bytes .../items/cosmic/mask/large_battery.png | Bin 0 -> 148 bytes .../textures/items/cosmic/mask/mainframe.png | Bin 0 -> 197 bytes .../items/cosmic/mask/medium_battery.png | Bin 0 -> 146 bytes .../textures/items/cosmic/mask/processor.png | Bin 0 -> 142 bytes .../items/cosmic/mask/small_battery.png | Bin 0 -> 140 bytes .../textures/items/cosmic/mask/smd.png | Bin 0 -> 170 bytes 18 files changed, 403 insertions(+), 4 deletions(-) create mode 100644 src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png.mcmeta create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/assembly.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/board.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/circuit_board.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/computer.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/large_battery.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/mainframe.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/medium_battery.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/processor.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/small_battery.png create mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/smd.png diff --git a/dependencies.gradle b/dependencies.gradle index 4ab055c1f2c..8f2bd9467ae 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -60,6 +60,11 @@ dependencies { // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. + //Implemented Dependencies + //This is temporary, will be removed pre-merge + + implementation rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 254183d6d88..e11d1f67847 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -1,7 +1,10 @@ package gregtech; +import codechicken.lib.texture.TextureUtils; + import gregtech.api.GTValues; import gregtech.api.GregTechAPI; +import gregtech.api.items.metaitem.MetaItem; import gregtech.api.modules.ModuleContainerRegistryEvent; import gregtech.api.persistence.PersistentData; import gregtech.api.util.Mods; @@ -67,6 +70,7 @@ public void onConstruction(FMLConstructionEvent event) { @EventHandler public void preInit(FMLPreInitializationEvent event) { moduleManager.onPreInit(event); + TextureUtils.addIconRegister(new MetaItem.MetaValueItem.CosmicTexture()); } @EventHandler diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index 595e3e0a9fc..96c166ed3ad 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -1,5 +1,10 @@ package gregtech.api.items.metaitem; +import codechicken.lib.model.ModelRegistryHelper; + +import codechicken.lib.texture.TextureUtils; +import codechicken.lib.util.TransformUtils; + import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechCapabilities; @@ -21,12 +26,22 @@ import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; import gregtech.api.util.Mods; +import gregtech.client.renderer.item.CosmicItemRenderer; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.common.ConfigHolder; +import morph.avaritia.api.ICosmicRenderItem; +import morph.avaritia.api.IHaloRenderItem; +import morph.avaritia.api.registration.IModelRegister; + +import morph.avaritia.init.AvaritiaTextures; + import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; @@ -77,6 +92,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -96,10 +112,11 @@ * rechargeable) LV battery with initial capacity 10000 EU */ @Optional.Interface( - modid = Mods.Names.ENDER_CORE, - iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") + modid = Mods.Names.ENDER_CORE, + iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item - implements ItemUIFactory, IOverlayRenderAware { + implements ItemUIFactory, IOverlayRenderAware, IHaloRenderItem, ICosmicRenderItem, + IModelRegister { private static final List> META_ITEMS = new ArrayList<>(); @@ -143,6 +160,9 @@ public void registerModels() { ResourceLocation resourceLocation = createItemModelPath(metaValueItem, "/" + (i + 1)); ModelBakery.registerItemVariants(this, resourceLocation); resourceLocations[i] = new ModelResourceLocation(resourceLocation, "inventory"); + ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); + IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); + ModelRegistryHelper.register(location, wrapped); } specialItemsModels.put((short) (metaItemOffset + itemMetaKey), resourceLocations); continue; @@ -153,6 +173,9 @@ public void registerModels() { } metaItemsModels.put((short) (metaItemOffset + itemMetaKey), new ModelResourceLocation(resourceLocation, "inventory")); + ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); + IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); + ModelRegistryHelper.register(location, wrapped); } } @@ -587,6 +610,69 @@ public String getItemStackDisplayName(ItemStack stack) { return super.getItemStackDisplayName(stack); } + @Override @SideOnly(Side.CLIENT) + public boolean shouldDrawHalo(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return false; + } + return metaValueItem.registerHalo(stack); + } + + @Override @SideOnly(Side.CLIENT) + public TextureAtlasSprite getHaloTexture(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem.registerHaloTexture(stack) == null) { + return AvaritiaTextures.HALO; + } + return MetaValueItem.CosmicTexture.haloTextures.get(metaValueItem.registerHaloTexture(stack)); + } + + @Override @SideOnly(Side.CLIENT) + public int getHaloColour(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return 0; + } + return metaValueItem.registerHaloColour(stack); + } + + @Override @SideOnly(Side.CLIENT) + public int getHaloSize(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return 0; + } + return metaValueItem.registerHaloSize(stack); + } + + @Override @SideOnly(Side.CLIENT) + public boolean shouldDrawPulse(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return false; + } + return metaValueItem.registerHaloPulse(stack); + } + + @SideOnly(Side.CLIENT) + public TextureAtlasSprite getMaskTexture(ItemStack stack, EntityLivingBase player) { + T metaValueItem = getItem(stack); + if (metaValueItem.registerMaskTexture(stack) == null) { + return AvaritiaTextures.INFINITY_SWORD_MASK; + } + return MetaValueItem.CosmicTexture.maskTextures.get(metaValueItem.registerMaskTexture(stack)); + } + + @SideOnly(Side.CLIENT) + public float getMaskOpacity(ItemStack stack, EntityLivingBase player) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return 0.0f; + } + return metaValueItem.registerMaskOpacity(stack); + } + @Override @SideOnly(Side.CLIENT) public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn, @NotNull List lines, @@ -774,6 +860,14 @@ public MetaItem getMetaItem() { private int maxStackSize = 64; private int modelAmount = 1; + private boolean drawHalo; + private String haloPath; + private int haloColour; + private int haloSize; + private boolean haloPulse; + private String maskPath; + private float maskOpacity; + @Nullable private CreativeTabs[] creativeTabsOverride; @@ -869,6 +963,52 @@ public MetaValueItem addComponents(IItemComponent... stats) { return this; } + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexturePath, int haloColourInt, int haloSizeInt) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTexturePath; + this.haloColour = haloColourInt; + this.haloSize = haloSizeInt; + if (haloTexturePath == null) { + throw new IllegalArgumentException("Cannot add null HaloTexturePath."); + } + CosmicTexture.registerHaloIcon(haloTexturePath); + return this; + } + + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexturePath, int haloColourInt, int haloSizeInt, boolean shouldDrawHaloPulse) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTexturePath; + this.haloColour = haloColourInt; + this.haloSize = haloSizeInt; + this.haloPulse = shouldDrawHaloPulse; + if (haloTexturePath == null) { + throw new IllegalArgumentException("Cannot add null HaloTexturePath."); + } + CosmicTexture.registerHaloIcon(haloTexturePath); + return this; + } + + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTextureString, int haloColourInt, int haloSizeInt, boolean shouldDrawHaloPulse, String maskTextureString, float maskOpacityFloat) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTextureString; + this.haloColour = haloColourInt; + this.haloSize = haloSizeInt; + this.haloPulse = shouldDrawHaloPulse; + this.maskPath = maskTextureString; + this.maskOpacity = maskOpacityFloat; + if (haloTextureString == null) { + throw new IllegalArgumentException("Cannot add null HaloTexturePath."); + } else { + CosmicTexture.registerHaloIcon(haloTextureString); + } + if (maskTextureString == null) { + throw new IllegalArgumentException("Cannot add null MaskTextureString."); + } else { + CosmicTexture.registerMaskIcon(maskTextureString); + } + return this; + } + protected void addItemComponentsInternal(IItemComponent... stats) { for (IItemComponent itemComponent : stats) { if (itemComponent instanceof IItemNameProvider) { @@ -1071,5 +1211,60 @@ public String toString() { .append("unlocalizedName", unlocalizedName) .toString(); } + + public boolean registerHalo (ItemStack stack) { + return drawHalo; + } + + public String registerHaloTexture(ItemStack stack) { + return haloPath; + + } + + public int registerHaloColour (ItemStack stack) { + return haloColour; + } + + public int registerHaloSize (ItemStack stack) { + return haloSize; + } + + public boolean registerHaloPulse (ItemStack stack) { + return haloPulse; + } + + public String registerMaskTexture (ItemStack stack) { + return maskPath; + } + + public float registerMaskOpacity (ItemStack stack) { + return maskOpacity; + } + + public static class CosmicTexture implements TextureUtils.IIconRegister { + public static Map haloTextures = new HashMap<>(); + public static Map maskTextures = new HashMap<>(); + public static ArrayList haloPath = new ArrayList<>(); + public static ArrayList cosmicPath = new ArrayList<>(); + + + public static void registerHaloIcon(String path) { + haloPath.add(path); + } + + public static void registerMaskIcon(String path) { + cosmicPath.add(path); + } + + @Override + public void registerIcons(TextureMap textureMap) { + haloPath.forEach(halo -> { + haloTextures.put(halo, textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/halo/" + halo))); + }); + cosmicPath.forEach(mask -> { + maskTextures.put(mask, textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/" + mask))); + }); + } + } } } diff --git a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java new file mode 100644 index 00000000000..8dab427efff --- /dev/null +++ b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java @@ -0,0 +1,190 @@ +package gregtech.client.renderer.item; + +import codechicken.lib.colour.Colour; +import codechicken.lib.model.ItemQuadBakery; +import codechicken.lib.model.bakedmodels.ModelProperties; +import codechicken.lib.model.bakedmodels.PerspectiveAwareBakedModel; +import codechicken.lib.util.TransformUtils; +import com.google.common.collect.ImmutableList; +import morph.avaritia.api.ICosmicRenderItem; +import morph.avaritia.api.IHaloRenderItem; +import morph.avaritia.client.render.item.WrappedItemRenderer; +import morph.avaritia.client.render.shader.CosmicShaderHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderItem; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.model.IModelState; + +import java.util.HashMap; +import java.util.List; +import java.util.Random; + +public class CosmicItemRenderer extends WrappedItemRenderer { + private static final HashMap spriteQuadCache = new HashMap(); + private Random randy = new Random(); + + public CosmicItemRenderer(IModelState state, IBakedModel model) { + super(state, model); + } + + public CosmicItemRenderer(IModelState state, WrappedItemRenderer.IWrappedModelGetter getter) { + super(state, getter); + } + + public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType transformType) { + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + Tessellator tess = Tessellator.getInstance(); + BufferBuilder buffer = tess.getBuffer(); + this.processLightLevel(transformType); + if (stack.getItem() instanceof IHaloRenderItem && transformType == ItemCameraTransforms.TransformType.GUI) { + IHaloRenderItem hri = (IHaloRenderItem)stack.getItem(); + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.disableDepth(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.disableAlpha(); + if (hri.shouldDrawHalo(stack)) { + Colour.glColourARGB(hri.getHaloColour(stack)); + TextureAtlasSprite sprite = hri.getHaloTexture(stack); + double spread = (double)hri.getHaloSize(stack) / 16.0; + double min = 0.0 - spread; + double max = 1.0 + spread; + float minU = sprite.getMinU(); + float maxU = sprite.getMaxU(); + float minV = sprite.getMinV(); + float maxV = sprite.getMaxV(); + buffer.begin(7, DefaultVertexFormats.POSITION_TEX); + buffer.pos(max, max, 0.0).tex((double)maxU, (double)minV).endVertex(); + buffer.pos(min, max, 0.0).tex((double)minU, (double)minV).endVertex(); + buffer.pos(min, min, 0.0).tex((double)minU, (double)maxV).endVertex(); + buffer.pos(max, min, 0.0).tex((double)maxU, (double)maxV).endVertex(); + tess.draw(); + } + + if (hri.shouldDrawPulse(stack)) { + GlStateManager.pushMatrix(); + double scale = this.randy.nextDouble() * 0.15 + 0.95; + double trans = (1.0 - scale) / 2.0; + GlStateManager.translate(trans, trans, 0.0); + GlStateManager.scale(scale, scale, 1.0001); + renderModel(this.wrapped, stack, 0.6F); + GlStateManager.popMatrix(); + } + + renderModel(this.wrapped, stack); + GlStateManager.enableAlpha(); + GlStateManager.enableDepth(); + GlStateManager.enableRescaleNormal(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } else { + renderModel(this.wrapped, stack); + + } + if (transformType == ItemCameraTransforms.TransformType.GUI) { + this.renderInventory(stack, this.renderEntity); + } else { + this.renderSimple(stack, this.renderEntity); + } + + } + protected void renderSimple(ItemStack stack, EntityLivingBase player) { + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + World world = player != null ? player.world : null; + IBakedModel model = this.wrapped.getOverrides().handleItemState(this.wrapped, stack, world, player); + renderModel(model, stack); + if (stack.getItem() instanceof ICosmicRenderItem) { + ICosmicRenderItem cri = (ICosmicRenderItem)stack.getItem(); + GlStateManager.disableAlpha(); + GlStateManager.depthFunc(514); + TextureAtlasSprite cosmicSprite = cri.getMaskTexture(stack, player); + IBakedModel cosmicModel = (IBakedModel)spriteQuadCache.computeIfAbsent(cosmicSprite, CosmicItemRenderer::computeModel); + CosmicShaderHelper.cosmicOpacity = cri.getMaskOpacity(stack, player); + CosmicShaderHelper.useShader(); + renderModel(cosmicModel, stack); + CosmicShaderHelper.releaseShader(); + GlStateManager.depthFunc(515); + GlStateManager.enableAlpha(); + } + + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + private static IBakedModel computeModel(TextureAtlasSprite sprite) { + List quads = ItemQuadBakery.bakeItem(ImmutableList.of(sprite)); + return new PerspectiveAwareBakedModel(quads, TransformUtils.DEFAULT_ITEM, new ModelProperties(true, false)); + } + + protected void renderInventory(ItemStack stack, EntityLivingBase player) { + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.disableAlpha(); + GlStateManager.disableDepth(); + World world = player != null ? player.world : null; + IBakedModel model = this.wrapped.getOverrides().handleItemState(this.wrapped, stack, world, player); + renderModel(model, stack); + if (stack.getItem() instanceof ICosmicRenderItem) { + ICosmicRenderItem cri = (ICosmicRenderItem)stack.getItem(); + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.disableAlpha(); + GlStateManager.disableDepth(); + TextureAtlasSprite sprite = cri.getMaskTexture(stack, player); + IBakedModel cosmicModel = (IBakedModel)spriteQuadCache.computeIfAbsent(sprite, CosmicItemRenderer::computeModel); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + CosmicShaderHelper.cosmicOpacity = cri.getMaskOpacity(stack, player); + CosmicShaderHelper.inventoryRender = true; + CosmicShaderHelper.useShader(); + renderModel(cosmicModel, stack); + CosmicShaderHelper.releaseShader(); + CosmicShaderHelper.inventoryRender = false; + GlStateManager.popMatrix(); + } + + GlStateManager.enableAlpha(); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableDepth(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + protected void processLightLevel(ItemCameraTransforms.TransformType transformType) { + switch (transformType) { + case GROUND: + if (this.entityPos != null) { + CosmicShaderHelper.setLightFromLocation(this.world, this.entityPos); + return; + } + break; + case THIRD_PERSON_LEFT_HAND: + case THIRD_PERSON_RIGHT_HAND: + case FIRST_PERSON_LEFT_HAND: + case FIRST_PERSON_RIGHT_HAND: + case HEAD: + if (this.renderEntity != null) { + CosmicShaderHelper.setLightFromLocation(this.world, this.entityPos); + return; + } + break; + case GUI: + CosmicShaderHelper.setLightLevel(1.2F); + return; + } + + CosmicShaderHelper.setLightLevel(1.0F); + } +} diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 3dfe1ffb666..a8f399cd71d 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -1101,7 +1101,7 @@ public void registerSubItems() { } // Misc 1000+ - NAN_CERTIFICATE = addItem(1000, "nan.certificate").setRarity(EnumRarity.EPIC); + NAN_CERTIFICATE = addItem(1000, "nan.certificate").setRarity(EnumRarity.EPIC).cosmicProperties(true, "halo_noise", -1711276033, 10); FERTILIZER = addItem(1001, "fertilizer").addComponents(new FertilizerBehavior()); BLACKLIGHT = addItem(1002, "blacklight"); diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo.png b/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo.png new file mode 100644 index 0000000000000000000000000000000000000000..5c6f1c505afb2984de00e7fb5ad05fdb5b75c131 GIT binary patch literal 3450 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png b/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png new file mode 100644 index 0000000000000000000000000000000000000000..ab4418124be98239efa270fbf5e7d2480efb43c4 GIT binary patch literal 31598 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 KFKezt(EkB1=iJ!< literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png.mcmeta b/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png.mcmeta new file mode 100644 index 00000000000..24f9c2fae39 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/items/cosmic/halo/halo_noise.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 1 + } +} diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/assembly.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/assembly.png new file mode 100644 index 0000000000000000000000000000000000000000..b7d08e71e049d30118679109491342ee7e88618a GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgN~<*V~B-+vP8iFj-?M5EL`}|eoCh(!_&Yo r29BAV4z6Ha%+_$=fV9DdhDJt)Pajz%l#LrePGInK^>bP0l+XkKg!lvI6;>1s;*b3=G_SAk65n?;%i4)6?^|c>J|nX=F7vK^-M3linSeT=;KF-XA1z@PgIfhxn?XXJu6{1-oD!M!Uk|4j}{|ryJ8+ZYEoCO|{#S9GGd?3u|u!Uk|4j}{|ryJ8+ZYEoCO|{#S9GGd?3u|ujyJpHsR~>)a69c%5~Z z`+;|plxD r0YTAUk5)Li*m0ZxQ}($bT4cwNQ_U<@pzg37Xg`CetDnm{r-UW|s~A+k literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/large_battery.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/large_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..8f9c4a464a55de15f883a39a96f5811752882aae GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQlm8V~B-+vIOg51`dgZCNd@_CV$$EHZm=+ o>5@~^@HLZQW8k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%xHZ(K}o!+b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/processor.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/processor.png new file mode 100644 index 0000000000000000000000000000000000000000..d3dbb8114c6d3eb1ee036d2da3df9ecd65e2e2c0 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR-ZKV~B-+vIOf6M`!25^%}yhwk-^yb8UGJ hC3I9Z`ZY8%GURIW{q9Jwd^g)BfJ0r literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/small_battery.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/small_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..609df2d949f7b7cb9dd7cb37df50dd0f4ee68929 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQBO4V~B-+vIOg4ITI6;KkSJb;@SyKmr|Mo fncEl>5*Qe6Okw5x$>g>hsF=ai)z4*}Q$iB}4$vV; literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/smd.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/smd.png new file mode 100644 index 0000000000000000000000000000000000000000..dbb2124d5f927a527f1ec58fe9d0c750d7fa0b7a GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=G_SAk65n?;%i-+oi9a#h%7#P6>!=WXd46Ph0-f6ZiK%*EuUHx3v IIVCg!0Mo87cK`qY literal 0 HcmV?d00001 From 7280648f401dccac5429df90fd1b5cb3305f36ca Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sun, 15 Dec 2024 17:37:03 +0000 Subject: [PATCH 159/168] MetaPrefixItem Cosmic Effects Added Cosmic Effect to MetaPrefixItem Class. This allows for all Materials in GregTech to use some Renderers from Avaritia. Changes to MetaItem and MetaPrefixItem to only allow cosmic effects if Avaritia is installed Lots of Mask textures for all Material sets --- dependencies.gradle | 7 +- src/main/java/gregtech/GregTechMod.java | 6 +- .../items/materialitem/MetaPrefixItem.java | 161 ++++++++- .../gregtech/api/items/metaitem/MetaItem.java | 307 ++++++++++++------ .../api/unification/material/Material.java | 63 ++++ .../material/properties/CosmicProperty.java | 180 ++++++++++ .../material/properties/PropertyKey.java | 1 + src/main/java/gregtech/api/util/Mods.java | 2 + .../renderer/item/CosmicItemRenderer.java | 17 + .../java/gregtech/common/items/MetaItem1.java | 2 +- .../textures/items/cosmic/mask/assembly.png | Bin 151 -> 0 bytes .../textures/items/cosmic/mask/board.png | Bin 167 -> 0 bytes .../items/cosmic/mask/circuit_board.png | Bin 198 -> 0 bytes .../textures/items/cosmic/mask/computer.png | Bin 255 -> 0 bytes .../items/cosmic/mask/large_battery.png | Bin 148 -> 0 bytes .../textures/items/cosmic/mask/mainframe.png | Bin 197 -> 0 bytes .../items/cosmic/mask/medium_battery.png | Bin 146 -> 0 bytes .../textures/items/cosmic/mask/processor.png | Bin 142 -> 0 bytes .../items/cosmic/mask/small_battery.png | Bin 140 -> 0 bytes .../textures/items/cosmic/mask/smd.png | Bin 170 -> 0 bytes .../items/material_sets/bright/bolt_mask.png | Bin 0 -> 567 bytes .../bright/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/bright/crushed_mask.png | Bin 0 -> 196 bytes .../bright/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/bright/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/bright/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/bright/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/bright/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/bright/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/bright/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/bright/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/bright/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/bright/gem_chipped_mask.png | Bin 0 -> 187 bytes .../bright/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/bright/gem_flawed_mask.png | Bin 0 -> 178 bytes .../bright/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/bright/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/bright/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/bright/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/bright/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/bright/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/bright/plate_dense_mask.png | Bin 0 -> 2806 bytes .../bright/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/bright/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/bright/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/bright/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/bright/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/bright/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/bright/spring_mask.png | Bin 0 -> 164 bytes .../bright/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/bright/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/bright/stick_mask.png | Bin 0 -> 196 bytes .../bright/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../bright/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../bright/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../bright/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../bright/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../bright/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/bright/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/certus/bolt_mask.png | Bin 0 -> 567 bytes .../certus/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/certus/crushed_mask.png | Bin 0 -> 196 bytes .../certus/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/certus/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/certus/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/certus/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/certus/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/certus/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/certus/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/certus/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/certus/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/certus/gem_chipped_mask.png | Bin 0 -> 187 bytes .../certus/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/certus/gem_flawed_mask.png | Bin 0 -> 178 bytes .../certus/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/certus/gem_mask.png | Bin 0 -> 573 bytes .../material_sets/certus/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/certus/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/certus/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/certus/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/certus/plate_dense_mask.png | Bin 0 -> 2806 bytes .../certus/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/certus/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/certus/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/certus/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/certus/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/certus/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/certus/spring_mask.png | Bin 0 -> 164 bytes .../certus/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/certus/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/certus/stick_mask.png | Bin 0 -> 196 bytes .../certus/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../certus/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../certus/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../certus/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../certus/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../certus/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/certus/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/diamond/bolt_mask.png | Bin 0 -> 567 bytes .../diamond/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/diamond/crushed_mask.png | Bin 0 -> 196 bytes .../diamond/crushed_purified_mask.png | Bin 0 -> 208 bytes .../diamond/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/diamond/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/diamond/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/diamond/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/diamond/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/diamond/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/diamond/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/diamond/gear_small_mask.png | Bin 0 -> 195 bytes .../diamond/gem_chipped_mask.png | Bin 0 -> 187 bytes .../diamond/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/diamond/gem_flawed_mask.png | Bin 0 -> 178 bytes .../diamond/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/diamond/gem_mask.png | Bin 0 -> 564 bytes .../material_sets/diamond/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/diamond/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/diamond/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/diamond/nugget_mask.png | Bin 0 -> 176 bytes .../diamond/plate_dense_mask.png | Bin 0 -> 2806 bytes .../diamond/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/diamond/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/diamond/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/diamond/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/diamond/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/diamond/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/diamond/spring_mask.png | Bin 0 -> 164 bytes .../diamond/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/diamond/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/diamond/stick_mask.png | Bin 0 -> 196 bytes .../diamond/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../diamond/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../diamond/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../diamond/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../diamond/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../diamond/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/diamond/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/dull/bolt_mask.png | Bin 0 -> 567 bytes .../dull/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../items/material_sets/dull/crushed_mask.png | Bin 0 -> 196 bytes .../dull/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/dull/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/dull/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/dull/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/dull/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/dull/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/dull/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/dull/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/dull/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/dull/gem_chipped_mask.png | Bin 0 -> 187 bytes .../material_sets/dull/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/dull/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/dull/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/dull/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/dull/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/dull/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/dull/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/dull/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/dull/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/dull/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/dull/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/dull/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/dull/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/dull/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/dull/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/dull/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/dull/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/dull/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/dull/stick_mask.png | Bin 0 -> 196 bytes .../dull/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../dull/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../dull/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../dull/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../dull/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../material_sets/dull/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/dull/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/emerald/bolt_mask.png | Bin 0 -> 567 bytes .../emerald/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/emerald/crushed_mask.png | Bin 0 -> 196 bytes .../emerald/crushed_purified_mask.png | Bin 0 -> 208 bytes .../emerald/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/emerald/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/emerald/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/emerald/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/emerald/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/emerald/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/emerald/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/emerald/gear_small_mask.png | Bin 0 -> 195 bytes .../emerald/gem_chipped_mask.png | Bin 0 -> 187 bytes .../emerald/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/emerald/gem_flawed_mask.png | Bin 0 -> 178 bytes .../emerald/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/emerald/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/emerald/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/emerald/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/emerald/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/emerald/nugget_mask.png | Bin 0 -> 176 bytes .../emerald/plate_dense_mask.png | Bin 0 -> 2806 bytes .../emerald/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/emerald/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/emerald/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/emerald/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/emerald/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/emerald/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/emerald/spring_mask.png | Bin 0 -> 164 bytes .../emerald/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/emerald/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/emerald/stick_mask.png | Bin 0 -> 196 bytes .../emerald/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../emerald/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../emerald/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../emerald/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../emerald/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../emerald/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/emerald/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/fine/bolt_mask.png | Bin 0 -> 567 bytes .../fine/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../items/material_sets/fine/crushed_mask.png | Bin 0 -> 196 bytes .../fine/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/fine/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/fine/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/fine/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/fine/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/fine/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/fine/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/fine/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/fine/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/fine/gem_chipped_mask.png | Bin 0 -> 191 bytes .../material_sets/fine/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/fine/gem_flawed_mask.png | Bin 0 -> 177 bytes .../material_sets/fine/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/fine/gem_mask.png | Bin 0 -> 547 bytes .../material_sets/fine/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/fine/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/fine/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/fine/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/fine/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/fine/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/fine/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/fine/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/fine/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/fine/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/fine/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/fine/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/fine/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/fine/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/fine/stick_mask.png | Bin 0 -> 196 bytes .../fine/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../fine/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../fine/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../fine/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../fine/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../material_sets/fine/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/fine/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/flint/bolt_mask.png | Bin 0 -> 567 bytes .../flint/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/flint/crushed_mask.png | Bin 0 -> 196 bytes .../flint/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/flint/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/flint/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/flint/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/flint/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/flint/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/flint/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/flint/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/flint/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/flint/gem_chipped_mask.png | Bin 0 -> 187 bytes .../flint/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/flint/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/flint/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/flint/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/flint/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/flint/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/flint/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/flint/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/flint/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/flint/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/flint/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/flint/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/flint/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/flint/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/flint/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/flint/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/flint/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/flint/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/flint/stick_mask.png | Bin 0 -> 196 bytes .../flint/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../flint/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../flint/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../flint/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../flint/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../flint/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/flint/wire_fine_mask.png | Bin 0 -> 199 bytes .../gem_horizontal/bolt_mask.png | Bin 0 -> 567 bytes .../crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../gem_horizontal/crushed_mask.png | Bin 0 -> 196 bytes .../gem_horizontal/crushed_purified_mask.png | Bin 0 -> 208 bytes .../gem_horizontal/dust_impure_mask.png | Bin 0 -> 196 bytes .../gem_horizontal/dust_mask.png | Bin 0 -> 196 bytes .../gem_horizontal/dust_pure_mask.png | Bin 0 -> 196 bytes .../gem_horizontal/dust_small_mask.png | Bin 0 -> 174 bytes .../gem_horizontal/dust_tiny_mask.png | Bin 0 -> 159 bytes .../gem_horizontal/foil_mask.png | Bin 0 -> 205 bytes .../gem_horizontal/gear_mask.png | Bin 0 -> 205 bytes .../gem_horizontal/gear_small_mask.png | Bin 0 -> 195 bytes .../gem_horizontal/gem_chipped_mask.png | Bin 0 -> 187 bytes .../gem_horizontal/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../gem_horizontal/gem_flawed_mask.png | Bin 0 -> 178 bytes .../gem_horizontal/gem_flawless_mask.png | Bin 0 -> 188 bytes .../material_sets/gem_horizontal/gem_mask.png | Bin 0 -> 530 bytes .../gem_horizontal/ingot_hot_mask.png | Bin 0 -> 195 bytes .../gem_horizontal/ingot_mask.png | Bin 0 -> 189 bytes .../gem_horizontal/lens_mask.png | Bin 0 -> 191 bytes .../gem_horizontal/nugget_mask.png | Bin 0 -> 176 bytes .../gem_horizontal/plate_dense_mask.png | Bin 0 -> 2806 bytes .../gem_horizontal/plate_double_mask.png | Bin 0 -> 1763 bytes .../gem_horizontal/plate_mask.png | Bin 0 -> 197 bytes .../gem_horizontal/ring_mask.png | Bin 0 -> 190 bytes .../gem_horizontal/rotor_mask.png | Bin 0 -> 207 bytes .../gem_horizontal/round_mask.png | Bin 0 -> 1534 bytes .../gem_horizontal/screw_mask.png | Bin 0 -> 179 bytes .../gem_horizontal/spring_mask.png | Bin 0 -> 164 bytes .../gem_horizontal/spring_small_mask.png | Bin 0 -> 160 bytes .../gem_horizontal/stick_long_mask.png | Bin 0 -> 1525 bytes .../gem_horizontal/stick_mask.png | Bin 0 -> 196 bytes .../tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../gem_horizontal/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../gem_horizontal/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../gem_horizontal/turbine_blade_mask.png | Bin 0 -> 200 bytes .../gem_horizontal/wire_fine_mask.png | Bin 0 -> 199 bytes .../material_sets/gem_vertical/bolt_mask.png | Bin 0 -> 567 bytes .../gem_vertical/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../gem_vertical/crushed_mask.png | Bin 0 -> 196 bytes .../gem_vertical/crushed_purified_mask.png | Bin 0 -> 208 bytes .../gem_vertical/dust_impure_mask.png | Bin 0 -> 196 bytes .../material_sets/gem_vertical/dust_mask.png | Bin 0 -> 196 bytes .../gem_vertical/dust_pure_mask.png | Bin 0 -> 196 bytes .../gem_vertical/dust_small_mask.png | Bin 0 -> 174 bytes .../gem_vertical/dust_tiny_mask.png | Bin 0 -> 159 bytes .../material_sets/gem_vertical/foil_mask.png | Bin 0 -> 205 bytes .../material_sets/gem_vertical/gear_mask.png | Bin 0 -> 205 bytes .../gem_vertical/gear_small_mask.png | Bin 0 -> 195 bytes .../items/material_sets/gem_vertical/gem.png | Bin 380 -> 327 bytes .../gem_vertical/gem_chipped_mask.png | Bin 0 -> 187 bytes .../gem_vertical/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../gem_vertical/gem_flawed_mask.png | Bin 0 -> 178 bytes .../gem_vertical/gem_flawless_mask.png | Bin 0 -> 188 bytes .../material_sets/gem_vertical/gem_mask.png | Bin 0 -> 539 bytes .../gem_vertical/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/gem_vertical/ingot_mask.png | Bin 0 -> 189 bytes .../material_sets/gem_vertical/lens_mask.png | Bin 0 -> 191 bytes .../gem_vertical/nugget_mask.png | Bin 0 -> 176 bytes .../gem_vertical/plate_dense_mask.png | Bin 0 -> 2806 bytes .../gem_vertical/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/gem_vertical/plate_mask.png | Bin 0 -> 197 bytes .../material_sets/gem_vertical/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/gem_vertical/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/gem_vertical/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/gem_vertical/screw_mask.png | Bin 0 -> 179 bytes .../gem_vertical/spring_mask.png | Bin 0 -> 164 bytes .../gem_vertical/spring_small_mask.png | Bin 0 -> 160 bytes .../gem_vertical/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/gem_vertical/stick_mask.png | Bin 0 -> 196 bytes .../gem_vertical/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../gem_vertical/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../gem_vertical/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../gem_vertical/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../gem_vertical/turbine_blade_mask.png | Bin 0 -> 200 bytes .../gem_vertical/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/glass/bolt_mask.png | Bin 0 -> 567 bytes .../glass/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/glass/crushed_mask.png | Bin 0 -> 196 bytes .../glass/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/glass/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/glass/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/glass/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/glass/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/glass/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/glass/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/glass/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/glass/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/glass/gem_chipped_mask.png | Bin 0 -> 187 bytes .../glass/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/glass/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/glass/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/glass/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/glass/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/glass/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/glass/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/glass/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/glass/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/glass/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/glass/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/glass/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/glass/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/glass/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/glass/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/glass/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/glass/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/glass/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/glass/stick_mask.png | Bin 0 -> 196 bytes .../glass/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../glass/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../glass/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../glass/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../glass/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../glass/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/glass/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/lapis/bolt_mask.png | Bin 0 -> 567 bytes .../lapis/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/lapis/crushed_mask.png | Bin 0 -> 196 bytes .../lapis/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/lapis/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/lapis/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/lapis/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/lapis/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/lapis/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/lapis/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/lapis/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/lapis/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/lapis/gem_chipped_mask.png | Bin 0 -> 191 bytes .../lapis/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/lapis/gem_flawed_mask.png | Bin 0 -> 177 bytes .../material_sets/lapis/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/lapis/gem_mask.png | Bin 0 -> 566 bytes .../material_sets/lapis/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/lapis/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/lapis/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/lapis/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/lapis/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/lapis/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/lapis/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/lapis/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/lapis/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/lapis/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/lapis/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/lapis/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/lapis/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/lapis/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/lapis/stick_mask.png | Bin 0 -> 196 bytes .../lapis/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../lapis/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../lapis/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../lapis/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../lapis/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../lapis/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/lapis/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/lignite/bolt_mask.png | Bin 0 -> 567 bytes .../lignite/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/lignite/crushed_mask.png | Bin 0 -> 196 bytes .../lignite/crushed_purified_mask.png | Bin 0 -> 208 bytes .../lignite/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/lignite/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/lignite/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/lignite/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/lignite/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/lignite/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/lignite/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/lignite/gear_small_mask.png | Bin 0 -> 195 bytes .../lignite/gem_chipped_mask.png | Bin 0 -> 187 bytes .../lignite/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/lignite/gem_flawed_mask.png | Bin 0 -> 178 bytes .../lignite/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/lignite/gem_mask.png | Bin 0 -> 565 bytes .../material_sets/lignite/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/lignite/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/lignite/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/lignite/nugget_mask.png | Bin 0 -> 176 bytes .../lignite/plate_dense_mask.png | Bin 0 -> 2806 bytes .../lignite/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/lignite/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/lignite/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/lignite/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/lignite/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/lignite/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/lignite/spring_mask.png | Bin 0 -> 164 bytes .../lignite/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/lignite/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/lignite/stick_mask.png | Bin 0 -> 196 bytes .../lignite/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../lignite/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../lignite/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../lignite/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../lignite/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../lignite/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/lignite/wire_fine_mask.png | Bin 0 -> 199 bytes .../material_sets/magnetic/bolt_mask.png | Bin 0 -> 567 bytes .../magnetic/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/magnetic/crushed_mask.png | Bin 0 -> 196 bytes .../magnetic/crushed_purified_mask.png | Bin 0 -> 208 bytes .../magnetic/dust_impure_mask.png | Bin 0 -> 196 bytes .../material_sets/magnetic/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/magnetic/dust_pure_mask.png | Bin 0 -> 196 bytes .../magnetic/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/magnetic/dust_tiny_mask.png | Bin 0 -> 159 bytes .../material_sets/magnetic/foil_mask.png | Bin 0 -> 205 bytes .../material_sets/magnetic/gear_mask.png | Bin 0 -> 205 bytes .../magnetic/gear_small_mask.png | Bin 0 -> 195 bytes .../magnetic/gem_chipped_mask.png | Bin 0 -> 187 bytes .../magnetic/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../magnetic/gem_flawed_mask.png | Bin 0 -> 178 bytes .../magnetic/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/magnetic/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/magnetic/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/magnetic/ingot_mask.png | Bin 0 -> 189 bytes .../material_sets/magnetic/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/magnetic/nugget_mask.png | Bin 0 -> 176 bytes .../magnetic/plate_dense_mask.png | Bin 0 -> 2806 bytes .../magnetic/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/magnetic/plate_mask.png | Bin 0 -> 197 bytes .../material_sets/magnetic/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/magnetic/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/magnetic/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/magnetic/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/magnetic/spring_mask.png | Bin 0 -> 164 bytes .../magnetic/spring_small_mask.png | Bin 0 -> 160 bytes .../magnetic/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/magnetic/stick_mask.png | Bin 0 -> 196 bytes .../magnetic/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../magnetic/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../magnetic/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../magnetic/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../magnetic/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../magnetic/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/magnetic/wire_fine_mask.png | Bin 0 -> 199 bytes .../material_sets/metallic/bolt_mask.png | Bin 0 -> 567 bytes .../metallic/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/metallic/crushed_mask.png | Bin 0 -> 196 bytes .../metallic/crushed_purified_mask.png | Bin 0 -> 208 bytes .../metallic/dust_impure_mask.png | Bin 0 -> 196 bytes .../material_sets/metallic/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/metallic/dust_pure_mask.png | Bin 0 -> 196 bytes .../metallic/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/metallic/dust_tiny_mask.png | Bin 0 -> 159 bytes .../material_sets/metallic/foil_mask.png | Bin 0 -> 205 bytes .../material_sets/metallic/gear_mask.png | Bin 0 -> 205 bytes .../metallic/gear_small_mask.png | Bin 0 -> 195 bytes .../metallic/gem_chipped_mask.png | Bin 0 -> 187 bytes .../metallic/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../metallic/gem_flawed_mask.png | Bin 0 -> 178 bytes .../metallic/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/metallic/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/metallic/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/metallic/ingot_mask.png | Bin 0 -> 189 bytes .../material_sets/metallic/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/metallic/nugget_mask.png | Bin 0 -> 176 bytes .../metallic/plate_dense_mask.png | Bin 0 -> 2806 bytes .../metallic/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/metallic/plate_mask.png | Bin 0 -> 197 bytes .../material_sets/metallic/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/metallic/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/metallic/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/metallic/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/metallic/spring_mask.png | Bin 0 -> 164 bytes .../metallic/spring_small_mask.png | Bin 0 -> 160 bytes .../metallic/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/metallic/stick_mask.png | Bin 0 -> 196 bytes .../metallic/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../metallic/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../metallic/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../metallic/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../metallic/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../metallic/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/metallic/wire_fine_mask.png | Bin 0 -> 199 bytes .../material_sets/netherstar/bolt_mask.png | Bin 0 -> 567 bytes .../netherstar/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/netherstar/crushed_mask.png | Bin 0 -> 196 bytes .../netherstar/crushed_purified_mask.png | Bin 0 -> 208 bytes .../netherstar/dust_impure_mask.png | Bin 0 -> 196 bytes .../material_sets/netherstar/dust_mask.png | Bin 0 -> 196 bytes .../netherstar/dust_pure_mask.png | Bin 0 -> 196 bytes .../netherstar/dust_small_mask.png | Bin 0 -> 174 bytes .../netherstar/dust_tiny_mask.png | Bin 0 -> 159 bytes .../material_sets/netherstar/foil_mask.png | Bin 0 -> 205 bytes .../material_sets/netherstar/gear_mask.png | Bin 0 -> 205 bytes .../netherstar/gear_small_mask.png | Bin 0 -> 195 bytes .../netherstar/gem_chipped_mask.png | Bin 0 -> 187 bytes .../netherstar/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../netherstar/gem_flawed_mask.png | Bin 0 -> 178 bytes .../netherstar/gem_flawless_mask.png | Bin 0 -> 188 bytes .../material_sets/netherstar/gem_mask.png | Bin 0 -> 552 bytes .../netherstar/ingot_hot_mask.png | Bin 0 -> 195 bytes .../material_sets/netherstar/ingot_mask.png | Bin 0 -> 189 bytes .../material_sets/netherstar/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/netherstar/nugget_mask.png | Bin 0 -> 176 bytes .../netherstar/plate_dense_mask.png | Bin 0 -> 2806 bytes .../netherstar/plate_double_mask.png | Bin 0 -> 1763 bytes .../material_sets/netherstar/plate_mask.png | Bin 0 -> 197 bytes .../material_sets/netherstar/ring_mask.png | Bin 0 -> 190 bytes .../material_sets/netherstar/rotor_mask.png | Bin 0 -> 207 bytes .../material_sets/netherstar/round_mask.png | Bin 0 -> 1534 bytes .../material_sets/netherstar/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/netherstar/spring_mask.png | Bin 0 -> 164 bytes .../netherstar/spring_small_mask.png | Bin 0 -> 160 bytes .../netherstar/stick_long_mask.png | Bin 0 -> 1525 bytes .../material_sets/netherstar/stick_mask.png | Bin 0 -> 196 bytes .../netherstar/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../netherstar/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../netherstar/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../netherstar/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../netherstar/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../netherstar/turbine_blade_mask.png | Bin 0 -> 200 bytes .../netherstar/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/opal/bolt_mask.png | Bin 0 -> 567 bytes .../opal/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../items/material_sets/opal/crushed_mask.png | Bin 0 -> 196 bytes .../opal/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/opal/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/opal/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/opal/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/opal/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/opal/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/opal/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/opal/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/opal/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/opal/gem_chipped_mask.png | Bin 0 -> 187 bytes .../material_sets/opal/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/opal/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/opal/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/opal/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/opal/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/opal/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/opal/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/opal/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/opal/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/opal/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/opal/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/opal/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/opal/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/opal/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/opal/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/opal/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/opal/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/opal/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/opal/stick_mask.png | Bin 0 -> 196 bytes .../opal/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../opal/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../opal/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../opal/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../opal/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../material_sets/opal/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/opal/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/quartz/bolt_mask.png | Bin 0 -> 567 bytes .../quartz/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/quartz/crushed_mask.png | Bin 0 -> 196 bytes .../quartz/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/quartz/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/quartz/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/quartz/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/quartz/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/quartz/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/quartz/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/quartz/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/quartz/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/quartz/gem_chipped_mask.png | Bin 0 -> 187 bytes .../quartz/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/quartz/gem_flawed_mask.png | Bin 0 -> 178 bytes .../quartz/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/quartz/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/quartz/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/quartz/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/quartz/lens_mask.png | Bin 0 -> 191 bytes .../material_sets/quartz/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/quartz/plate_dense_mask.png | Bin 0 -> 2806 bytes .../quartz/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/quartz/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/quartz/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/quartz/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/quartz/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/quartz/screw_mask.png | Bin 0 -> 179 bytes .../material_sets/quartz/spring_mask.png | Bin 0 -> 164 bytes .../quartz/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/quartz/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/quartz/stick_mask.png | Bin 0 -> 196 bytes .../quartz/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../quartz/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../quartz/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../quartz/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../quartz/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../quartz/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/quartz/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/rough/bolt_mask.png | Bin 0 -> 567 bytes .../rough/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/rough/crushed_mask.png | Bin 0 -> 196 bytes .../rough/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/rough/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/rough/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/rough/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/rough/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/rough/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/rough/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/rough/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/rough/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/rough/gem_chipped_mask.png | Bin 0 -> 187 bytes .../rough/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/rough/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/rough/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/rough/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/rough/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/rough/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/rough/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/rough/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/rough/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/rough/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/rough/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/rough/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/rough/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/rough/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/rough/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/rough/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/rough/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/rough/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/rough/stick_mask.png | Bin 0 -> 196 bytes .../rough/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../rough/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../rough/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../rough/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../rough/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../rough/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/rough/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/ruby/bolt_mask.png | Bin 0 -> 567 bytes .../ruby/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../items/material_sets/ruby/crushed_mask.png | Bin 0 -> 196 bytes .../ruby/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/ruby/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/ruby/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/ruby/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/ruby/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/ruby/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/ruby/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/ruby/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/ruby/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/ruby/gem_chipped_mask.png | Bin 0 -> 187 bytes .../material_sets/ruby/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/ruby/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/ruby/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/ruby/gem_mask.png | Bin 0 -> 558 bytes .../material_sets/ruby/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/ruby/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/ruby/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/ruby/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/ruby/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/ruby/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/ruby/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/ruby/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/ruby/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/ruby/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/ruby/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/ruby/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/ruby/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/ruby/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/ruby/stick_mask.png | Bin 0 -> 196 bytes .../ruby/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../ruby/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../ruby/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../ruby/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../ruby/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../material_sets/ruby/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/ruby/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/sand/bolt_mask.png | Bin 0 -> 567 bytes .../sand/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../items/material_sets/sand/crushed_mask.png | Bin 0 -> 196 bytes .../sand/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/sand/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/sand/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/sand/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/sand/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/sand/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/sand/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/sand/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/sand/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/sand/gem_chipped_mask.png | Bin 0 -> 187 bytes .../material_sets/sand/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/sand/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/sand/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/sand/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/sand/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/sand/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/sand/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/sand/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/sand/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/sand/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/sand/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/sand/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/sand/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/sand/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/sand/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/sand/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/sand/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/sand/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/sand/stick_mask.png | Bin 0 -> 196 bytes .../sand/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../sand/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../sand/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../sand/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../sand/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../material_sets/sand/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/sand/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/shiny/bolt_mask.png | Bin 0 -> 567 bytes .../shiny/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../material_sets/shiny/crushed_mask.png | Bin 0 -> 196 bytes .../shiny/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/shiny/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/shiny/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/shiny/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/shiny/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/shiny/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/shiny/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/shiny/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/shiny/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/shiny/gem_chipped_mask.png | Bin 0 -> 187 bytes .../shiny/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/shiny/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/shiny/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/shiny/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/shiny/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/shiny/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/shiny/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/shiny/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/shiny/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/shiny/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/shiny/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/shiny/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/shiny/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/shiny/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/shiny/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/shiny/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/shiny/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/shiny/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/shiny/stick_mask.png | Bin 0 -> 196 bytes .../shiny/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../shiny/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../shiny/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../shiny/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../shiny/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../shiny/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/shiny/wire_fine_mask.png | Bin 0 -> 199 bytes .../items/material_sets/wood/bolt_mask.png | Bin 0 -> 567 bytes .../wood/crushed_centrifuged_mask.png | Bin 0 -> 191 bytes .../items/material_sets/wood/crushed_mask.png | Bin 0 -> 196 bytes .../wood/crushed_purified_mask.png | Bin 0 -> 208 bytes .../material_sets/wood/dust_impure_mask.png | Bin 0 -> 196 bytes .../items/material_sets/wood/dust_mask.png | Bin 0 -> 196 bytes .../material_sets/wood/dust_pure_mask.png | Bin 0 -> 196 bytes .../material_sets/wood/dust_small_mask.png | Bin 0 -> 174 bytes .../material_sets/wood/dust_tiny_mask.png | Bin 0 -> 159 bytes .../items/material_sets/wood/foil_mask.png | Bin 0 -> 205 bytes .../items/material_sets/wood/gear_mask.png | Bin 0 -> 205 bytes .../material_sets/wood/gear_small_mask.png | Bin 0 -> 195 bytes .../material_sets/wood/gem_chipped_mask.png | Bin 0 -> 187 bytes .../material_sets/wood/gem_exquisite_mask.png | Bin 0 -> 184 bytes .../material_sets/wood/gem_flawed_mask.png | Bin 0 -> 178 bytes .../material_sets/wood/gem_flawless_mask.png | Bin 0 -> 188 bytes .../items/material_sets/wood/gem_mask.png | Bin 0 -> 552 bytes .../material_sets/wood/ingot_hot_mask.png | Bin 0 -> 195 bytes .../items/material_sets/wood/ingot_mask.png | Bin 0 -> 189 bytes .../items/material_sets/wood/lens_mask.png | Bin 0 -> 191 bytes .../items/material_sets/wood/nugget_mask.png | Bin 0 -> 176 bytes .../material_sets/wood/plate_dense_mask.png | Bin 0 -> 2806 bytes .../material_sets/wood/plate_double_mask.png | Bin 0 -> 1763 bytes .../items/material_sets/wood/plate_mask.png | Bin 0 -> 197 bytes .../items/material_sets/wood/ring_mask.png | Bin 0 -> 190 bytes .../items/material_sets/wood/rotor_mask.png | Bin 0 -> 207 bytes .../items/material_sets/wood/round_mask.png | Bin 0 -> 1534 bytes .../items/material_sets/wood/screw_mask.png | Bin 0 -> 179 bytes .../items/material_sets/wood/spring_mask.png | Bin 0 -> 164 bytes .../material_sets/wood/spring_small_mask.png | Bin 0 -> 160 bytes .../material_sets/wood/stick_long_mask.png | Bin 0 -> 1525 bytes .../items/material_sets/wood/stick_mask.png | Bin 0 -> 196 bytes .../wood/tool_head_buzz_saw_mask.png | Bin 0 -> 569 bytes .../wood/tool_head_chainsaw_mask.png | Bin 0 -> 556 bytes .../wood/tool_head_drill_mask.png | Bin 0 -> 552 bytes .../wood/tool_head_screwdriver_mask.png | Bin 0 -> 182 bytes .../wood/tool_head_wrench_mask.png | Bin 0 -> 189 bytes .../material_sets/wood/turbine_blade_mask.png | Bin 0 -> 200 bytes .../material_sets/wood/wire_fine_mask.png | Bin 0 -> 199 bytes 879 files changed, 625 insertions(+), 121 deletions(-) create mode 100644 src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/assembly.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/board.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/circuit_board.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/computer.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/large_battery.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/mainframe.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/medium_battery.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/processor.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/small_battery.png delete mode 100644 src/main/resources/assets/gregtech/textures/items/cosmic/mask/smd.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/bright/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/certus/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/diamond/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/dull/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/emerald/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/fine/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/flint/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/glass/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lapis/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/lignite/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/metallic/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/opal/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/quartz/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/rough/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/ruby/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/sand/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/shiny/wire_fine_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/bolt_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_centrifuged_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_purified_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_impure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_pure_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_tiny_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/foil_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gear_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gear_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_chipped_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_exquisite_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_flawed_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_flawless_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/ingot_hot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/ingot_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/lens_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/nugget_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/plate_dense_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/plate_double_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/plate_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/ring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/rotor_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/round_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/screw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/spring_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/spring_small_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/stick_long_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/stick_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_buzz_saw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_chainsaw_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_drill_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_screwdriver_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_wrench_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/turbine_blade_mask.png create mode 100644 src/main/resources/assets/gregtech/textures/items/material_sets/wood/wire_fine_mask.png diff --git a/dependencies.gradle b/dependencies.gradle index 8f2bd9467ae..60612a56a77 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -51,6 +51,7 @@ dependencies { compileOnly("curse.maven:journeymap-32274:5172461") // Journeymap 5.7.1p3 compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 compileOnly("curse.maven:xaeros-263420:5394758") // Xaero's Minimap 24.2.0 + compileOnly rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 compileOnly rfg.deobf("curse.maven:opencomputers-223008:5274236") // OpenComputers 1.8.5+179e1c3 compileOnly rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 compileOnly rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 @@ -60,11 +61,7 @@ dependencies { // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - //Implemented Dependencies - //This is temporary, will be removed pre-merge - - implementation rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 - + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index e11d1f67847..e45a6ffc613 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -31,6 +31,8 @@ import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; +import static gregtech.api.util.Mods.Avaritia; + @Mod(modid = GTValues.MODID, name = GTValues.MOD_NAME, acceptedMinecraftVersions = "[1.12.2,1.13)", @@ -70,7 +72,9 @@ public void onConstruction(FMLConstructionEvent event) { @EventHandler public void preInit(FMLPreInitializationEvent event) { moduleManager.onPreInit(event); - TextureUtils.addIconRegister(new MetaItem.MetaValueItem.CosmicTexture()); + if (Avaritia.isModLoaded()) { + TextureUtils.addIconRegister(new MetaItem.MetaValueItem.CosmicTexture()); + } } @EventHandler diff --git a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java index 35172727add..2a25b659c35 100644 --- a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java +++ b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java @@ -1,14 +1,19 @@ package gregtech.api.items.materialitem; +import codechicken.lib.model.ModelRegistryHelper; +import codechicken.lib.util.TransformUtils; + import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.damagesources.DamageSources; import gregtech.api.items.armor.ArmorMetaItem; import gregtech.api.items.metaitem.StandardMetaItem; +import gregtech.api.items.metaitem.MetaItem.MetaValueItem.CosmicTexture; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.info.MaterialIconSet; +import gregtech.api.unification.material.properties.CosmicProperty; import gregtech.api.unification.material.properties.DustProperty; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.material.properties.ToolProperty; @@ -16,10 +21,20 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; +import gregtech.client.renderer.item.CosmicItemRenderer; + +import morph.avaritia.api.ICosmicRenderItem; +import morph.avaritia.api.IHaloRenderItem; +import morph.avaritia.api.registration.IModelRegister; +import morph.avaritia.init.AvaritiaTextures; + import net.minecraft.block.BlockCauldron; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -29,6 +44,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -36,16 +52,27 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -public class MetaPrefixItem extends StandardMetaItem { +import java.util.*; + +import static gregtech.api.util.Mods.Avaritia; + +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.ICosmicRenderItem") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.IHaloRenderItem") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.registration.IModelRegister") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.init.AvaritiaTextures") +public class MetaPrefixItem extends StandardMetaItem implements IHaloRenderItem, ICosmicRenderItem, + IModelRegister { private final MaterialRegistry registry; private final OrePrefix prefix; - public static final Map purifyMap = new HashMap<>(); static { @@ -124,13 +151,24 @@ public void registerModels() { Map alreadyRegistered = new Short2ObjectOpenHashMap<>(); for (short metaItem : metaItems.keySet()) { MaterialIconSet materialIconSet = getMaterial(metaItem).getMaterialIconSet(); - short registrationKey = (short) (prefix.id + materialIconSet.id); if (!alreadyRegistered.containsKey(registrationKey)) { ResourceLocation resourceLocation = Objects.requireNonNull(prefix.materialIconType) .getItemModelPath(materialIconSet); ModelBakery.registerItemVariants(this, resourceLocation); alreadyRegistered.put(registrationKey, new ModelResourceLocation(resourceLocation, "inventory")); + + + if (Avaritia.isModLoaded()) { + ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); + IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); + ModelRegistryHelper.register(location, wrapped); + + String processedLocation = resourceLocation.toString().replace("gregtech:", "gregtech:items/"); + String processedIdentifier = resourceLocation.toString() + .replace("gregtech:material_sets", "identifier"); + CosmicTexture.registerSpecialMaskIcon(processedIdentifier + "_mask", processedLocation + "_mask"); + } } ModelResourceLocation resourceLocation = alreadyRegistered.get(registrationKey); metaItemsModels.put(metaItem, resourceLocation); @@ -277,4 +315,111 @@ protected void addMaterialTooltip(@NotNull List lines, @NotNull ItemStac lines.addAll(this.prefix.tooltipFunc.apply(getMaterial(itemStack))); } } + + @Override @SideOnly(Side.CLIENT) + public boolean shouldDrawHalo(ItemStack stack) { + + Material material = getMaterial(stack); + assert material != null; + + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getShouldDrawHalo()) { + return prop.getShouldDrawHalo(); + } else { + return false; + } + } + + @Override @SideOnly(Side.CLIENT) + public TextureAtlasSprite getHaloTexture(ItemStack stack) { + + Material material = getMaterial(stack); + assert material != null; + + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getHaloTexture() != null) { + return CosmicTexture.haloTextures.get(prop.getHaloTexture()); + } else { + return AvaritiaTextures.HALO; + } + } + + @Override @SideOnly(Side.CLIENT) + public int getHaloColour(ItemStack stack) { + + Material material = getMaterial(stack); + assert material != null; + + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getHaloColour() != null) { + return Integer.decode("0x7F" + prop.getHaloColour()); + } else { + return 0; + } + } + + @Override @SideOnly(Side.CLIENT) + public int getHaloSize(ItemStack stack) { + + Material material = getMaterial(stack); + assert material != null; + + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getHaloSize() != 0) { + return prop.getHaloSize(); + } else { + return 0; + } + + } + + @Override @SideOnly(Side.CLIENT) + public boolean shouldDrawPulse(ItemStack stack) { + Material material = getMaterial(stack); + assert material != null; + + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getHaloPulse()) { + return prop.getHaloPulse(); + } else { + return false; + } + } + + @SideOnly(Side.CLIENT) + public TextureAtlasSprite getMaskTexture(ItemStack stack, EntityLivingBase player) { + Material material = getMaterial(stack); + assert material != null; + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getMaskOpacity() != null) { + int meta = stack.getMetadata(); + MaterialIconSet materialIconSet = getMaterial(meta).getMaterialIconSet(); + ResourceLocation resourceLocation = Objects.requireNonNull(prefix.materialIconType) + .getItemModelPath(materialIconSet); + String identifier = resourceLocation.toString().replace("gregtech:material_sets", "identifier"); + return CosmicTexture.specialMaskTextures.get(identifier + "_mask"); + } else { + return CosmicTexture.specialMaskTextures.get("fallback"); + } + } + + @SideOnly(Side.CLIENT) + public float getMaskOpacity(ItemStack stack, EntityLivingBase player) { + Material material = getMaterial(stack); + assert material != null; + + CosmicProperty prop = material.getProperty(PropertyKey.COSMIC); + + if (material.hasProperty(PropertyKey.COSMIC) && prop.getMaskOpacity() != null) { + return prop.getMaskOpacity(); + } else { + return 0.0f; + } + } } diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index 96c166ed3ad..46aa03b8654 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -1,7 +1,6 @@ package gregtech.api.items.metaitem; import codechicken.lib.model.ModelRegistryHelper; - import codechicken.lib.texture.TextureUtils; import codechicken.lib.util.TransformUtils; @@ -33,7 +32,6 @@ import morph.avaritia.api.ICosmicRenderItem; import morph.avaritia.api.IHaloRenderItem; import morph.avaritia.api.registration.IModelRegister; - import morph.avaritia.init.AvaritiaTextures; import net.minecraft.client.Minecraft; @@ -98,6 +96,8 @@ import java.util.Objects; import java.util.Set; +import static gregtech.api.util.Mods.Avaritia; + /** * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. These items even can be edible, have custom * behaviours, be electric or act like fluid containers! They can also have different burn time, plus be handheld, @@ -114,6 +114,18 @@ @Optional.Interface( modid = Mods.Names.ENDER_CORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.ICosmicRenderItem") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.IHaloRenderItem") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.registration.IModelRegister") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.init.AvaritiaTextures") public abstract class MetaItem.MetaValueItem> extends Item implements ItemUIFactory, IOverlayRenderAware, IHaloRenderItem, ICosmicRenderItem, IModelRegister { @@ -160,9 +172,13 @@ public void registerModels() { ResourceLocation resourceLocation = createItemModelPath(metaValueItem, "/" + (i + 1)); ModelBakery.registerItemVariants(this, resourceLocation); resourceLocations[i] = new ModelResourceLocation(resourceLocation, "inventory"); - ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); - IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); - ModelRegistryHelper.register(location, wrapped); + + if (Avaritia.isModLoaded()) { + ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); + IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, + (modelRegistry) -> modelRegistry.getObject(location)); + ModelRegistryHelper.register(location, wrapped); + } } specialItemsModels.put((short) (metaItemOffset + itemMetaKey), resourceLocations); continue; @@ -173,9 +189,12 @@ public void registerModels() { } metaItemsModels.put((short) (metaItemOffset + itemMetaKey), new ModelResourceLocation(resourceLocation, "inventory")); - ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); - IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); - ModelRegistryHelper.register(location, wrapped); + if (Avaritia.isModLoaded()) { + ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); + IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, + (modelRegistry) -> modelRegistry.getObject(location)); + ModelRegistryHelper.register(location, wrapped); + } } } @@ -610,68 +629,6 @@ public String getItemStackDisplayName(ItemStack stack) { return super.getItemStackDisplayName(stack); } - @Override @SideOnly(Side.CLIENT) - public boolean shouldDrawHalo(ItemStack stack) { - T metaValueItem = getItem(stack); - if (metaValueItem == null){ - return false; - } - return metaValueItem.registerHalo(stack); - } - - @Override @SideOnly(Side.CLIENT) - public TextureAtlasSprite getHaloTexture(ItemStack stack) { - T metaValueItem = getItem(stack); - if (metaValueItem.registerHaloTexture(stack) == null) { - return AvaritiaTextures.HALO; - } - return MetaValueItem.CosmicTexture.haloTextures.get(metaValueItem.registerHaloTexture(stack)); - } - - @Override @SideOnly(Side.CLIENT) - public int getHaloColour(ItemStack stack) { - T metaValueItem = getItem(stack); - if (metaValueItem == null){ - return 0; - } - return metaValueItem.registerHaloColour(stack); - } - - @Override @SideOnly(Side.CLIENT) - public int getHaloSize(ItemStack stack) { - T metaValueItem = getItem(stack); - if (metaValueItem == null){ - return 0; - } - return metaValueItem.registerHaloSize(stack); - } - - @Override @SideOnly(Side.CLIENT) - public boolean shouldDrawPulse(ItemStack stack) { - T metaValueItem = getItem(stack); - if (metaValueItem == null){ - return false; - } - return metaValueItem.registerHaloPulse(stack); - } - - @SideOnly(Side.CLIENT) - public TextureAtlasSprite getMaskTexture(ItemStack stack, EntityLivingBase player) { - T metaValueItem = getItem(stack); - if (metaValueItem.registerMaskTexture(stack) == null) { - return AvaritiaTextures.INFINITY_SWORD_MASK; - } - return MetaValueItem.CosmicTexture.maskTextures.get(metaValueItem.registerMaskTexture(stack)); - } - - @SideOnly(Side.CLIENT) - public float getMaskOpacity(ItemStack stack, EntityLivingBase player) { - T metaValueItem = getItem(stack); - if (metaValueItem == null){ - return 0.0f; - } - return metaValueItem.registerMaskOpacity(stack); - } @Override @SideOnly(Side.CLIENT) @@ -832,6 +789,68 @@ public ModularUI createUI(PlayerInventoryHolder holder, EntityPlayer entityPlaye public void renderItemOverlayIntoGUI(@NotNull ItemStack stack, int xPosition, int yPosition) { ToolChargeBarRenderer.renderBarsItem(this, stack, xPosition, yPosition); } + @Override @SideOnly(Side.CLIENT) + public boolean shouldDrawHalo(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return false; + } + return metaValueItem.registerHalo(stack); + } + + @Override @SideOnly(Side.CLIENT) + public TextureAtlasSprite getHaloTexture(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem.registerHaloTexture(stack) == null) { + return AvaritiaTextures.HALO; + } + return MetaValueItem.CosmicTexture.haloTextures.get(metaValueItem.registerHaloTexture(stack)); + } + + @Override @SideOnly(Side.CLIENT) + public int getHaloColour(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return 0; + } + return Integer.decode("0x7F" + metaValueItem.registerHaloColour(stack)); + } + + @Override @SideOnly(Side.CLIENT) + public int getHaloSize(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return 0; + } + return metaValueItem.registerHaloSize(stack); + } + + @Override @SideOnly(Side.CLIENT) + public boolean shouldDrawPulse(ItemStack stack) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return false; + } + return metaValueItem.registerHaloPulse(stack); + } + + @SideOnly(Side.CLIENT) + public TextureAtlasSprite getMaskTexture(ItemStack stack, EntityLivingBase player) { + T metaValueItem = getItem(stack); + if (metaValueItem.registerMaskTexture(stack) == null) { + return AvaritiaTextures.INFINITY_SWORD_MASK; + } + return MetaValueItem.CosmicTexture.maskTextures.get(metaValueItem.registerMaskTexture(stack)); + } + + @SideOnly(Side.CLIENT) + public float getMaskOpacity(ItemStack stack, EntityLivingBase player) { + T metaValueItem = getItem(stack); + if (metaValueItem == null){ + return 0.0f; + } + return metaValueItem.registerMaskOpacity(stack); + } public class MetaValueItem { @@ -862,7 +881,7 @@ public MetaItem getMetaItem() { private boolean drawHalo; private String haloPath; - private int haloColour; + private String haloColour; private int haloSize; private boolean haloPulse; private String maskPath; @@ -963,52 +982,118 @@ public MetaValueItem addComponents(IItemComponent... stats) { return this; } - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexturePath, int haloColourInt, int haloSizeInt) { - this.drawHalo = shouldDrawHalo; - this.haloPath = haloTexturePath; - this.haloColour = haloColourInt; - this.haloSize = haloSizeInt; - if (haloTexturePath == null) { - throw new IllegalArgumentException("Cannot add null HaloTexturePath."); + /** + * This function requires the latest version of Avaritia to be Installed + * ... + * + * @param shouldDrawHalo enables the Halo effect for a specified MetaItem.
+ * @param haloTexture the Halo Texture for a specified MetaItem in the form of a String : Example "halo".
+ * @param haloColour the Colour the Halo will have in the form of a Hex String : Example "00FF00" (hex color for green).
+ * @param haloSize The size of the halo : Example 10.
+ * @param shouldDrawPulse Whether the MetaItem will pulse like Avaritia's Infinity Ingot : Example true.
+ * @param maskTexture The String Location of the Mask texture the MetaItem will use as a Cosmic Effect : Example "nan".
+ * @param maskOpacity The Opacity of the Cosmic Effect, Use in combination with maskTexture : Example 1.0f.
+ */ + @Optional.Method(modid = Mods.Names.AVARITIA) + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse, String maskTexture, float maskOpacity) { + if (Avaritia.isModLoaded()) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + this.haloPulse = shouldDrawPulse; + this.maskPath = maskTexture; + this.maskOpacity = maskOpacity; + if (haloTexture == null) { + throw new IllegalArgumentException("Cannot add null haloTexture."); + } else { + CosmicTexture.registerHaloIcon(haloTexture); + } + if (maskTexture == null) { + throw new IllegalArgumentException("Cannot add null MaskTextureString."); + } else { + CosmicTexture.registerMaskIcon(maskTexture); + } } - CosmicTexture.registerHaloIcon(haloTexturePath); return this; } - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexturePath, int haloColourInt, int haloSizeInt, boolean shouldDrawHaloPulse) { - this.drawHalo = shouldDrawHalo; - this.haloPath = haloTexturePath; - this.haloColour = haloColourInt; - this.haloSize = haloSizeInt; - this.haloPulse = shouldDrawHaloPulse; - if (haloTexturePath == null) { - throw new IllegalArgumentException("Cannot add null HaloTexturePath."); + @Optional.Method(modid = Mods.Names.AVARITIA) + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, String maskTexture, float maskOpacity) { + if (Avaritia.isModLoaded()) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + this.maskPath = maskTexture; + this.maskOpacity = maskOpacity; + if (haloTexture == null) { + throw new IllegalArgumentException("Cannot add null haloTexture."); + } else { + CosmicTexture.registerHaloIcon(haloTexture); + } + if (maskTexture == null) { + throw new IllegalArgumentException("Cannot add null MaskTextureString."); + } else { + CosmicTexture.registerMaskIcon(maskTexture); + } } - CosmicTexture.registerHaloIcon(haloTexturePath); return this; } - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTextureString, int haloColourInt, int haloSizeInt, boolean shouldDrawHaloPulse, String maskTextureString, float maskOpacityFloat) { - this.drawHalo = shouldDrawHalo; - this.haloPath = haloTextureString; - this.haloColour = haloColourInt; - this.haloSize = haloSizeInt; - this.haloPulse = shouldDrawHaloPulse; - this.maskPath = maskTextureString; - this.maskOpacity = maskOpacityFloat; - if (haloTextureString == null) { - throw new IllegalArgumentException("Cannot add null HaloTexturePath."); - } else { - CosmicTexture.registerHaloIcon(haloTextureString); + @Optional.Method(modid = Mods.Names.AVARITIA) + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse) { + if (Avaritia.isModLoaded()) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + this.haloPulse = shouldDrawPulse; + if (haloTexture == null) { + throw new IllegalArgumentException("Cannot add null haloTexture."); + } + CosmicTexture.registerHaloIcon(haloTexture); } - if (maskTextureString == null) { - throw new IllegalArgumentException("Cannot add null MaskTextureString."); - } else { - CosmicTexture.registerMaskIcon(maskTextureString); + return this; + } + + @Optional.Method(modid = Mods.Names.AVARITIA) + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize) { + if (Avaritia.isModLoaded()) { + this.drawHalo = shouldDrawHalo; + this.haloPath = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + if (haloTexture == null) { + throw new IllegalArgumentException("Cannot add null Halo."); + } + CosmicTexture.registerHaloIcon(haloTexture); + } + return this; + } + + @Optional.Method(modid = Mods.Names.AVARITIA) + public MetaValueItem cosmicProperties(String maskTexture, Float maskOpacity) { + if (Avaritia.isModLoaded()) { + this.maskPath = maskTexture; + this.maskOpacity = maskOpacity; + if (maskTexture == null) { + throw new IllegalArgumentException("Cannot add null Mask."); + } + CosmicTexture.registerMaskIcon(maskTexture); } return this; } + @Optional.Method(modid = Mods.Names.AVARITIA) + public MetaValueItem cosmicProperties(boolean shouldDrawPulse) { + if (Avaritia.isModLoaded()) { + this.haloPulse = shouldDrawPulse; + } + return this; + } + + protected void addItemComponentsInternal(IItemComponent... stats) { for (IItemComponent itemComponent : stats) { if (itemComponent instanceof IItemNameProvider) { @@ -1221,7 +1306,7 @@ public String registerHaloTexture(ItemStack stack) { } - public int registerHaloColour (ItemStack stack) { + public String registerHaloColour (ItemStack stack) { return haloColour; } @@ -1244,9 +1329,10 @@ public float registerMaskOpacity (ItemStack stack) { public static class CosmicTexture implements TextureUtils.IIconRegister { public static Map haloTextures = new HashMap<>(); public static Map maskTextures = new HashMap<>(); + public static Map specialMaskTextures = new HashMap<>(); public static ArrayList haloPath = new ArrayList<>(); public static ArrayList cosmicPath = new ArrayList<>(); - + public static Map specialCosmicPath = new HashMap<>(); public static void registerHaloIcon(String path) { haloPath.add(path); @@ -1256,6 +1342,10 @@ public static void registerMaskIcon(String path) { cosmicPath.add(path); } + public static void registerSpecialMaskIcon(String stack, String path) { + specialCosmicPath.put(stack, path); + } + @Override public void registerIcons(TextureMap textureMap) { haloPath.forEach(halo -> { @@ -1264,6 +1354,11 @@ public void registerIcons(TextureMap textureMap) { cosmicPath.forEach(mask -> { maskTextures.put(mask, textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/" + mask))); }); + + specialCosmicPath.forEach((key, value) -> { + specialMaskTextures.put(key, textureMap.registerSprite(new ResourceLocation(value))); + specialMaskTextures.put("fallback", textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/fallback"))); + }); } } } diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 18770e5325c..37499324d93 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -16,6 +16,7 @@ import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.SmallDigits; import net.minecraft.enchantment.Enchantment; @@ -26,6 +27,9 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import crafttweaker.annotations.ZenRegister; + +import net.minecraftforge.fml.common.Optional; + import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +43,8 @@ import java.util.function.Consumer; import java.util.function.UnaryOperator; +import static gregtech.api.util.Mods.Avaritia; + @ZenClass("mods.gregtech.material.Material") @ZenRegister public class Material implements Comparable { @@ -798,6 +804,63 @@ public Builder polymer(int harvestLevel) { return this; } + /** + * Add a {@link CosmicProperty} to this Material.
+ * This function requires the latest version of Avaritia to be Installed + * ... + * @param shouldDrawHalo enables the Halo effect for a specified Material.
+ * @param haloTexture the Halo Texture for a specific Material in the form of a String : Example "halo".
+ * @param haloColour the Colour the Halo will have in the form of a Hex String : Example "00FF00" (hex color for green).
+ * @param haloSize The size of the halo : Example 10.
+ * @param shouldDrawPulse If the Material Item will pulse like Avaritia's Infinity Ingot : Example true.
+ * @param shouldDrawCosmic If the Material Item will have Avaritia's Cosmic Effect : Example true.
+ * All the locations for these are autogenerated and follow the same path as the MaterialIconSet the material uses: Example "gregtech:textures/items/material_sets/dull/dust_mask + * @param maskOpacity The Opacity of the Cosmic Effect, Use in combination with shouldDrawCosmic : Example 1.0f.
+ */ + @Optional.Method(modid = Mods.Names.AVARITIA) + public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse, boolean shouldDrawCosmic, Float maskOpacity) { + if (Avaritia.isModLoaded()) { + properties.setProperty(PropertyKey.COSMIC, + new CosmicProperty(shouldDrawHalo, haloTexture, haloColour, haloSize, shouldDrawPulse, + shouldDrawCosmic, maskOpacity)); + } + return this; + } + + @Optional.Method(modid = Mods.Names.AVARITIA) + public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse) { + if (Avaritia.isModLoaded()) { + properties.setProperty(PropertyKey.COSMIC, + new CosmicProperty(shouldDrawHalo, haloTexture, haloColour, haloSize, shouldDrawPulse)); + } + return this; + } + + @Optional.Method(modid = Mods.Names.AVARITIA) + public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize) { + if (Avaritia.isModLoaded()) { + properties.setProperty(PropertyKey.COSMIC, + new CosmicProperty(shouldDrawHalo, haloTexture, haloColour, haloSize)); + } + return this; + } + + @Optional.Method(modid = Mods.Names.AVARITIA) + public Builder cosmic( boolean shouldDrawCosmic, Float maskOpacity) { + if (Avaritia.isModLoaded()) { + properties.setProperty(PropertyKey.COSMIC, new CosmicProperty(shouldDrawCosmic, maskOpacity)); + } + return this; + } + + @Optional.Method(modid = Mods.Names.AVARITIA) + public Builder cosmic(boolean shouldDrawPulse) { + if (Avaritia.isModLoaded()) { + properties.setProperty(PropertyKey.COSMIC, new CosmicProperty(shouldDrawPulse)); + } + return this; + } + public Builder burnTime(int burnTime) { DustProperty prop = properties.getProperty(PropertyKey.DUST); if (prop == null) { diff --git a/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java b/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java new file mode 100644 index 00000000000..08b0d09dc26 --- /dev/null +++ b/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java @@ -0,0 +1,180 @@ +package gregtech.api.unification.material.properties; + +import gregtech.api.items.metaitem.MetaItem.MetaValueItem.CosmicTexture; + +import static gregtech.api.util.Mods.Avaritia; + +public class CosmicProperty implements IMaterialProperty { + + /** + * Whether the Material will draw a Halo + * Example: true + */ + private boolean shouldDrawHalo; + + /** + * Halo Texture path, Use this with shouldDrawHalo + * Example: "halo" + *

+ */ + private String haloTexture; + + /** + * Halo Colour in the form of a Hex, Use this with shouldDrawHalo + * Example: "00FF00" Hex colour for Green + *

+ */ + private String haloColour; + + /** + * Halo Size, Use this with shouldDrawHalo + * Example: 8 Max Value of 10 + *

+ */ + private int haloSize; + + /** + * Whether the Material Item will pulse like Avaritia's Infinity Ingot + * Example: true + *

+ */ + private boolean shouldDrawPulse; + + /** + * Whether the Material Set will draw Cosmic Effect + * Example: true + * All the locations for these are autogenerated and follow the same path as the MaterialIconSet the material uses + * Example: "gregtech:textures/items/material_sets/dull/dust_mask + *

+ */ + private boolean shouldDrawCosmic; + + /** + * Mask Opacity for cosmic effect, Use this with shouldDrawCosmic + * Example: 1.0f + *

+ */ + private Float maskOpacity; + + public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse, boolean shouldDrawCosmic, Float maskOpacity) { + if (Avaritia.isModLoaded()) { + this.shouldDrawHalo = shouldDrawHalo; + this.haloTexture = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + this.shouldDrawPulse = shouldDrawPulse; + this.shouldDrawCosmic = shouldDrawCosmic; + this.maskOpacity = maskOpacity; + CosmicTexture.registerHaloIcon(haloTexture); + } + } + + public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse) { + if (Avaritia.isModLoaded()) { + this.shouldDrawHalo = shouldDrawHalo; + this.haloTexture = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + this.shouldDrawPulse = shouldDrawPulse; + CosmicTexture.registerHaloIcon(haloTexture); + } + } + + public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize) { + if (Avaritia.isModLoaded()) { + this.shouldDrawHalo = shouldDrawHalo; + this.haloTexture = haloTexture; + this.haloColour = haloColour; + this.haloSize = haloSize; + CosmicTexture.registerHaloIcon(haloTexture); + } + } + + public CosmicProperty(boolean shouldDrawCosmic, Float maskOpacity) { + if (Avaritia.isModLoaded()) { + this.shouldDrawCosmic = shouldDrawCosmic; + this.maskOpacity = maskOpacity; + } + + } + + public CosmicProperty(boolean shouldDrawPulse) { + if (Avaritia.isModLoaded()) { + this.shouldDrawPulse = shouldDrawPulse; + } + } + + public boolean getShouldDrawHalo() { + return shouldDrawHalo; + } + + public String getHaloTexture() { + return haloTexture; + } + + public String getHaloColour() { + return haloColour; + } + + public int getHaloSize() { + return haloSize; + } + + public boolean getHaloPulse() { + return shouldDrawPulse; + } + + public boolean shouldDrawCosmic() { + return shouldDrawCosmic; + } + public Float getMaskOpacity() { + return maskOpacity; + } + @Override + public void verifyProperty(MaterialProperties properties) { + properties.ensureSet(PropertyKey.DUST, true); + } + + public static class Builder { + + private boolean shouldDrawHalo; + private String haloTexture; + private String haloColour; + private int haloSize; + private boolean shouldDrawPulse; + private boolean shouldDrawCosmic; + private Float maskOpacity; + + public Builder() {} + + public Builder shouldDrawHalo(boolean shouldDrawHalo) { + this.shouldDrawHalo = shouldDrawHalo; + return this; + } + + public Builder haloTexture(String haloTexture) { + this.haloTexture = haloTexture; + return this; + } + public Builder haloColour(String haloColour) { + this.haloColour = haloColour; + return this; + } + public Builder haloSize(int haloSize) { + this.haloSize = haloSize; + return this; + } + public Builder shouldDrawPulse(boolean shouldDrawPulse) { + this.shouldDrawPulse = shouldDrawPulse; + return this; + } + public Builder shouldDrawCosmic(boolean shouldDrawCosmic) { + this.shouldDrawCosmic = shouldDrawCosmic; + return this; + } + public Builder maskOpacity(Float maskOpacity) { + this.maskOpacity = maskOpacity; + return this; + } + } +} diff --git a/src/main/java/gregtech/api/unification/material/properties/PropertyKey.java b/src/main/java/gregtech/api/unification/material/properties/PropertyKey.java index 5dc2234a40e..3cb01cd4567 100644 --- a/src/main/java/gregtech/api/unification/material/properties/PropertyKey.java +++ b/src/main/java/gregtech/api/unification/material/properties/PropertyKey.java @@ -17,6 +17,7 @@ public class PropertyKey { public static final PropertyKey ROTOR = new PropertyKey<>("rotor", RotorProperty.class); public static final PropertyKey WIRE = new PropertyKey<>("wire", WireProperties.class); public static final PropertyKey WOOD = new PropertyKey<>("wood", WoodProperty.class); + public static final PropertyKey COSMIC = new PropertyKey<>("cosmic", CosmicProperty.class); // Empty property used to allow property-less Materials without removing base type enforcement public static final PropertyKey EMPTY = new PropertyKey<>("empty", EmptyProperty.class); diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java index 609f71c1008..3e9f9a4451b 100644 --- a/src/main/java/gregtech/api/util/Mods.java +++ b/src/main/java/gregtech/api/util/Mods.java @@ -24,6 +24,7 @@ public enum Mods { AdvancedRocketry(Names.ADVANCED_ROCKETRY), AppliedEnergistics2(Names.APPLIED_ENERGISTICS2), + Avaritia(Names.AVARITIA), Baubles(Names.BAUBLES), BinnieCore(Names.BINNIE_CORE), BiomesOPlenty(Names.BIOMES_O_PLENTY), @@ -94,6 +95,7 @@ public static class Names { public static final String ADVANCED_ROCKETRY = "advancedrocketry"; public static final String APPLIED_ENERGISTICS2 = "appliedenergistics2"; + public static final String AVARITIA = "avaritia"; public static final String BAUBLES = "baubles"; public static final String BINNIE_CORE = "binniecore"; public static final String BIOMES_O_PLENTY = "biomesoplenty"; diff --git a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java index 8dab427efff..85246cf662a 100644 --- a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java +++ b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java @@ -6,10 +6,14 @@ import codechicken.lib.model.bakedmodels.PerspectiveAwareBakedModel; import codechicken.lib.util.TransformUtils; import com.google.common.collect.ImmutableList; + +import gregtech.api.util.Mods; + import morph.avaritia.api.ICosmicRenderItem; import morph.avaritia.api.IHaloRenderItem; import morph.avaritia.client.render.item.WrappedItemRenderer; import morph.avaritia.client.render.shader.CosmicShaderHelper; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; @@ -24,11 +28,24 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.World; import net.minecraftforge.common.model.IModelState; +import net.minecraftforge.fml.common.Optional; import java.util.HashMap; import java.util.List; import java.util.Random; +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.ICosmicRenderItem") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.IHaloRenderItem") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.client.render.item.WrappedItemRenderer") +@Optional.Interface( + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.client.render.shader.CosmicShaderHelper") public class CosmicItemRenderer extends WrappedItemRenderer { private static final HashMap spriteQuadCache = new HashMap(); private Random randy = new Random(); diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index a8f399cd71d..3dfe1ffb666 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -1101,7 +1101,7 @@ public void registerSubItems() { } // Misc 1000+ - NAN_CERTIFICATE = addItem(1000, "nan.certificate").setRarity(EnumRarity.EPIC).cosmicProperties(true, "halo_noise", -1711276033, 10); + NAN_CERTIFICATE = addItem(1000, "nan.certificate").setRarity(EnumRarity.EPIC); FERTILIZER = addItem(1001, "fertilizer").addComponents(new FertilizerBehavior()); BLACKLIGHT = addItem(1002, "blacklight"); diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/assembly.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/assembly.png deleted file mode 100644 index b7d08e71e049d30118679109491342ee7e88618a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgN~<*V~B-+vP8iFj-?M5EL`}|eoCh(!_&Yo r29BAV4z6Ha%+_$=fV9DdhDJt)Pajz%l#LrePGInK^>bP0l+XkKg!lvI6;>1s;*b3=G_SAk65n?;%i4)6?^|c>J|nX=F7vK^-M3linSeT=;KF-XA1z@PgIfhxn?XXJu6{1-oD!M!Uk|4j}{|ryJ8+ZYEoCO|{#S9GGd?3u|u!Uk|4j}{|ryJ8+ZYEoCO|{#S9GGd?3u|ujyJpHsR~>)a69c%5~Z z`+;|plxD r0YTAUk5)Li*m0ZxQ}($bT4cwNQ_U<@pzg37Xg`CetDnm{r-UW|s~A+k diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/large_battery.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/large_battery.png deleted file mode 100644 index 8f9c4a464a55de15f883a39a96f5811752882aae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQlm8V~B-+vIOg51`dgZCNd@_CV$$EHZm=+ o>5@~^@HLZQW8k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%xHZ(K}o!+b diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/processor.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/processor.png deleted file mode 100644 index d3dbb8114c6d3eb1ee036d2da3df9ecd65e2e2c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR-ZKV~B-+vIOf6M`!25^%}yhwk-^yb8UGJ hC3I9Z`ZY8%GURIW{q9Jwd^g)BfJ0r diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/small_battery.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/small_battery.png deleted file mode 100644 index 609df2d949f7b7cb9dd7cb37df50dd0f4ee68929..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQBO4V~B-+vIOg4ITI6;KkSJb;@SyKmr|Mo fncEl>5*Qe6Okw5x$>g>hsF=ai)z4*}Q$iB}4$vV; diff --git a/src/main/resources/assets/gregtech/textures/items/cosmic/mask/smd.png b/src/main/resources/assets/gregtech/textures/items/cosmic/mask/smd.png deleted file mode 100644 index dbb2124d5f927a527f1ec58fe9d0c750d7fa0b7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=G_SAk65n?;%i-+oi9a#h%7#P6>!=WXd46Ph0-f6ZiK%*EuUHx3v IIVCg!0Mo87cK`qY diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/bright/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/bright/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##b@?P)4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XQ000XQ0h0Lxr2qf`KS@MER47wz&ru2hAP57{dH+j?*5;J< z5$u7ah!xb6F{n;~`V)sc?ojgsvQ5Aj=1ec<;6HP}4ZS`=2MU-2LL&fsv;fop00000 LNkvXXu0mjfN=W&X literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/ingot_hot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/ingot_hot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5040854dc6866e7e5c35153380ae36d5306a81 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLxiV`V~Bhu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/certus/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/certus/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XQ000XQ0h0Lxr2qf`Hc3Q5R47wpU_=89I0P6N7+@?oA1VSS zA$*7kh=B1i1;89+KBfSOM~nc5p_l>~4#RXhG5`Qj#{i25xEH?w0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/diamond/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/emerald/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..22609663aba7e6256be58c2f255e0c894d145e24 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zC}`s8;uxY4oSfjo%oD)HGJ)kljS3@&d@#cyH7|x^?A(n4vlxu#^Du7E6%gy;|186l bz`?-a>A}#NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c32089972e07c6a5f72e1a2049abef1e307d224e GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vL6~vUPv)gSK{rnq#}EtuNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00009a7bBm000XQ000XQ0h0Lxr2qf`MM*?K zR5(xNk}(PZAPmH!FTbDbCiM`cPKp^@5;_!~r}zLsQuA3v((vlM+RM%q$jZdPiHu)x l!jFOY17rg(lL@TkJLnoo5EfQxjza(d002ovPDHLkV1l^U^#A|> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/ingot_hot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/ingot_hot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5040854dc6866e7e5c35153380ae36d5306a81 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLxiV`V~Bhu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/fine/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/fine/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/flint/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/flint/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00009a7bBm000XQ000XQ0h0Lxr2qf`G)Y83 zR5(v#U>F6A$ef0ThX2TXe4wGBfsp~(08%u=Ktn?VBNMtHsbJIqDi}a# U5bLDIHvj+t07*qoM6N<$f&^*kWB>pF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ingot_hot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ingot_hot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5040854dc6866e7e5c35153380ae36d5306a81 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLxiV`V~Bhu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_horizontal/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem.png index c5522e1b38f725a4cc54fd1bca2d33e72291e5a8..114b9d714e12b7efbf95a74d0b6d01eea41a3e6c 100644 GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}-0G|-ofPjGi|Nk#sxbW=Rv&WAgFDom1`t)gQYwLy$8x|~BP+VNx)6>({ z)m2kdQ(s>n7Z;bAnYnrM=Iz_JM@L7$c<~}FEv==cB|kqOXx{zhoR5H%WJ!=;Fwjh_ zfPvA3YdcU8XMsm#F#`iP(8b&WjBAzmmI4J6JY5_^G=gi-Kjdmq;9+@?d)7pE`pm1p z?K4{z1YP=j`*@+jj<`lU2R}vzmnDt!l$n)`R|ke09J`P*yR9&9n>XvbhHsa8j57Co w{a|zrOX(IZds^Dz$+hG0lo?r%KYP!X-sB^Y-e{J+5NH>Jr>mdKI;Vst04^+wZU6uP delta 364 zcmV-y0h9j60{jAy8Gi-<001BJ|6u?C00v@9M??Vs0RI60puMM)00009a7bBm000XS z000XS0e@s)kpKVy2XskIMF-vi5D*Rs1?R6E0003ANklvaMERaF77EDK%Np{nXS7w)5f#l~rx5JJ%RJ(gvy z7Z}HpX_}blnPuzs3V>;v-~ULvzihnSZZu7U5Q5|JNRlM$1cD%-C<=64=WsaS`#y0T zqiGt3VSKhRj$;hNpznKzVW2EaG)+SYfe_-UR(X}i|71bg8s{H{|CzY%%-OU60000< KMNUMnLSTZ_HJrTw diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XQ000XQ0h0Lxr2qf`9Z5t%R47wpU_=89*aa9M04@OKgGGjz d0EShu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/gem_vertical/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/glass/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/glass/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..22609663aba7e6256be58c2f255e0c894d145e24 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zC}`s8;uxY4oSfjo%oD)HGJ)kljS3@&d@#cyH7|x^?A(n4vlxu#^Du7E6%gy;|186l bz`?-a>A}#NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c32089972e07c6a5f72e1a2049abef1e307d224e GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vL6~vUPv)gSK{rnq#}EtuNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00009a7bBm000XQ000XQ0h0Lxr2qf`SV=@d zR5(w~lED%H5C{e1%lmUqnaT@|1AENu4h^E$6hF`~a|1KugaITAIsyYLS&&Et2U}S) z1+rWR%nnYkua`J(a4LJ!Pw@XB74R};0!XIa5+ms^I(w@fm9Nv`CIA2c07*qoM6N<$ Eg6_rl+yDRo literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ingot_hot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ingot_hot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5040854dc6866e7e5c35153380ae36d5306a81 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLxiV`V~Bhu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lapis/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XQ000XQ0h0Lxr2qf`H%UZ6R47wpU_=89#0xM$Sughu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/lignite/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/magnetic/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/netherstar/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/opal/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/opal/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/quartz/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/rough/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/rough/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XQ000XQ0h0Lxr2qf`FiAu~R47wpU_=89I0P6#07(GMhloH3 w7=Q}E`5+MxLI%_lz_10=9hfe~^a~OI07(%5fHXC(s{jB107*qoM6N<$f@8evMgRZ+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ingot_hot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ingot_hot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ce5040854dc6866e7e5c35153380ae36d5306a81 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLxiV`V~Bhu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/ruby/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/sand/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/sand/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/shiny/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/bolt_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/bolt_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b2c4ffaefc5219ecacd737769198288c81ea705 GIT binary patch literal 567 zcmV-70?7S|P)4Tx04UFukv&MmKpe$iQ?()$MLQI6$WWauh>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb8}L3krMxx6k3D|9vt`M-Mz=%J3y$Fm}Yg11DbA| z$#_gmXI90)D}oq67y1#FnPtpLQUYzq*FAiEy^HcJ{BQKCS&IQak$9FFrcJy-JiTcf zocD=CtRSnz=fqx##3obxUVJTqjblJmqNVlm&sN(-}ssS!^RM^sIxd?D?z z%6W^kR;sYZJ^2fRS$$=h>okWE$0C*>L4<+|iYUQGlvbS-3rX6Kweb(Reu-QPxr$)q zSU?#XWY-V=2fw?ua+4EYQZNQ|zBtau2oTr>>Q%@2K6ae?3E+PQuJoqATmxo4Nv}4w z$Pv)D4P0C|HDwRD+yTN*hHT2NEa!Ny6I%3tbuoetpeA0#7Z0C4AE1<4Q*nAucv z!*ew`x@4b{!6}-*<#Oh&(H4nSnC?=d*y21be002ovPDHLk FV1ga<@}d9$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_centrifuged_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_centrifuged_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae305211b4dfc6fce1421e6d793f9c65773e8 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##@f9F5mzF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..4b579d1fa44f44fa92de90be33a3707c44102899 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##MIx!)WC)z>C<5GgzCfya!4oYwY jia1Z~aoftO!N5>|is5ys!tp~uLl`_={an^LB{Ts5$*VH| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_purified_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/crushed_purified_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..7d521ab19ec630d69f78a5e33a40d3f10044223a GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##Kir`@fe8TPXzw3<7(Z7wZT`EeyPNh$TF wU`x!o6Ax`%r@Je7sXu!5Xm8c^WAS3*@hS|9XFPeT4m6O#)78&qol`;+0PY$;VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_impure_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_impure_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3c787d3d21a30d476fd33389434df393af36a705 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4+}mTw$6&z0^z{GybzBpV=-q25Xl^_jdqiZeOYhAMRhL6D)I_At2G-c; i>Ke@BT^N4X>xny@)s z=XjDF+8rt|eeDgNg8~XqQc9d>EHJs*ki@*9jgezPHS6sE?u;A;1`G_(mWr~QEtUTV PG>*a3)z4*}Q$iB}#D6aB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_tiny_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/dust_tiny_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..74285d5bae4638e2fff0f4e04887cac9f74cd291 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNdh$V~B-+vIJ|htci)qANE8IaqWbbOA-vR z$`krSb;BHEwj~+2aC%MV)%bQuV}XQ$0RzLQ7(tc?-wYLj`WZZ3{an^LB{Ts5(!eLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/foil_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/foil_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8d25f5a6304632673234d0f7aed76e161075e9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%;4nd;uxY4T-xo)#bCg3KH-v3a rnXquru|UT8`dNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCp$r;uxY4T-wdZ#bCg}bp5}*t!b--FUQwa!TmgZPnKMB;5jVxHbG#o$}QdvML!yU rPV(4zX5C@d298V89V-pDx`v87Twth_e0x~|Xc~j3tDnm{r-UW|nyx!b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gear_small_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gear_small_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..32143cc16e185c0297806a925a1b72c0ac6cc542 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXZ^;uxY4+}q8_#h}2$wEcg*)im>N4zH9~2bK8$HW$oP|G+ef(Piq*?|dfP#J6!U gn6D^NTq}M;Cewi7=oi+w2%s4Zp00i_>zopr01c=#jQ{`u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_chipped_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_chipped_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1b71c97f10df5e6b5a5442766fa018a22c4fecd1 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##y$kVVK_5H9?7C(ZaSvvaK7$I0eKQ Z7?N@rwmR+DTLRR};OXk;vd$@?2>|F}E`9(2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_exquisite_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_exquisite_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..351455f3bf8e302804928b17592b15d529caefdf GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##$G^w`U1s=! VAy($ZW02bzJYD@<);T3K0RU0jEyDl+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_flawed_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/gem_flawed_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd57dadaeda7819d43fb1ed912725dae0e1d5fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP&{S>##4Tx04UFukv&MmKpe$iQ>7{u5j%)DWT*;aK~%(1t5Adrp;l;qmz@Ois^Fr;eVrB%~%ZZiNv$aFm2)u;^|G> z;Ji;9VtH95J|`YC>4LwAiI9>Klt6Pm7SdMl7dm7{l#%UhJe5>P^&o3_p#&DP5}QiaHTi=r7AGizuye{gcFCW#_?00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWDoI2^R47wpU_=895E2X!0uVk#1Vq62 qU=apnK1gKX1TY+i>2yrbAp-zBkN|NZUNW-)0000hu#Ji0 lkCsk*x0v^)r@rG9#^Pi}zVyQii-2}8c)I$ztaD0e0ssOCJ{$l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/ingot_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/ingot_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..3b35c37469ac99b43a5b58d88c9e1d0cf4408deb GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXi{;uxY4oSfjo%u~T4aUf>~1GB^d76qFQ4rU>Kou*Su`5d;gzA{jeyOPKu$9Nv7 Y$N2?A?VBE_W}t2cPgg&ebxsLQ02Zz;H~;_u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/lens_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/lens_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..8db435f2675e83342bdc275e0f6bbe1384280e56 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zLx`t~V~B-+vP8iFj-`eU&d!JHHH3K@YSv^K zvRpJ>#9Y!GV9{c7m|>HmPr$4k2J_B{+ldU%xVmBuKCtmDifCYTTIaA$mc@Xlfw83d gf+?TafddQ-XEw_SStw001Dem^>FVdQ&MBb@07F|eN&o-= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/nugget_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/nugget_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..646ba11114a24d7083c4c88379c58d8e4af6e56d GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgR7^DV~B-+vIHwnPkeT%U?KyPNHwGQf*TBb7@qLPG@5fIG&C|Y96BW2`Q{8~ Q8_+-oPgg&ebxsLQ0O^4)xBvhE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/plate_dense_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/plate_dense_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4878ae8dff56a26d0de204dd05792a649138 GIT binary patch literal 2806 zcmdT`&u`;I6!!9S=~A&02cSa8ayb+UXKW`@o0M(Qx>QZjrZ*<`B(a)!ytdn< zguIxX+g#$ud-~bn-m6kVloY-kvD#V3Ii8F7$_q};D z-y6S=wl=RUE-Wo@9Jjc!Uf+i2MfN@aIQ*`N&o$t2F4(?unY;bN%fG_liSDYo%5h(P za^WF<62?z$U2U!%9UZ~nUwU7B3y;Ub?ajs`?&oi$H(~UQx4si_+=b`a_Z;`>XD@Qx zg5We;VavR#TXc}aHf@vKXy5^wQgT5Q+qlyp_>+qkMk-$fgaJM3?vWR@k+~RB0 zC%l>~ik6%&^Cc}Ot6Etpyv{3$cF{f%)r7*&K` z7r)$pByhEKHt+@_IC+L64r0$7DK_P3Ux{dzx7uo5?`Q$Tq_kg+<*=2kk+0R*@t63OYmRHvVep!PW?h&9vRtH&LsC^F zMHZ!^sN|b6$fm4Ipr3*+NhyjLnPD(Npf(QiSvWG-EDN=r&cT^DrpPpdY3dtp5MtLN z8}%yWoO2voSG9soaIqj3?IIELYN0H`NENZBl6J|mq+;HR(#yKf5Z9@-$AkgIab4Qf z0`kex>sCoAL+z=eUC0+iStf0-bS;$y{@tkw~+|HKoG55Lj!ya)@6L-uK zq2~Grv=a`oPgc7ifwL4`Oqg{`GaHCqlzr#F+w1`E|Ld(jTZ#Nnw|b&VtB2h#v8yN% zWMcS-gNe^7T^UK4%@&biTY8830~}VJ0qzpyxm^QIjY%M5dTrEbpZX@XNi}bvdFF`^ zdu!-W*q}fhm6vRwW40{1#p<-b7okgv1Ro@`-?3wQI_tP|x?_4e>p1m$+jYV!+<4Iv zXUr2H_IlH!Eoea3M5;wq&8r5QHD~c#&WQ9|bqB8FfL$|kaqKZWF~@D^B)8N=>=vJT zsn!66%Yv*PV)in^zUJjmn>Mt&cBbP_WmCttvg2)E-g{}oG|t5(;88Csg5XgQasAS?wTE%+#X|b>CBN_Y{r~dD zZtL3m+Ql_VlGd9$jW(Q*WY?Md;eP|2>%g&+w6ASSx9&Xt3ka*dx>J{=&)zxvCwTzm z2Y0V`w~vpH;r8eLr(eNwU)pYU?nys>j-LVPp=jrYM3T;)&#o2e{SO`mo%4QoFWqyl z+f)Pv!i38UqaXsbBvr4DB0~3hD!aVrhc)H5FTYk~pVgEbMF%_47VrBzM=|dlwYv0Z zpH`T1^~(BMbz}oWz*8cRfUa2DDO=s2fCgJ6zM((OaAGIjby;-ou{xZ384IEX3VKICC~X=aSkxo&h2 z4<_Ld zFnKcbXsW;)B;_>)s;41bL^|$jmW_4WG!fJg;~eThKQNM#<-mgZ-gp_Pd%=nee9o**yTdVX@`9dq^I;n z4oifW4oS@GJt)F|_no>#APG4UEAHp}F(rnbb8=d#=Xb(&H%;s}n-23>k z*Z00{{nh;b=ITeQw|_YPNS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXl|;uxY4+*X;Ky z`hb(Q!XE#}Sq?`Iu1$QIXwNY<@`K{Dg=gzF&MIBUmak^i>%m;M!^A<}=Y)xp^|hbo gT%jH2^^6BtJUtZz&N)m}0vgZY>FVdQ&MBb@09PhCJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/rotor_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/rotor_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc7cdfd58bff339e84e0a1368ea5ce2f4e131a2 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zDCpwp;uxY4oZ7=E#Gt^!^7H@l(^jH0FRqm}l>f@Lqf??xIv{gmrk8`Y*YU~GPH}#+ tK_-U#4LmOH>aS`MV|=FbLwNfg@pJ)(gWH8!b%5qEc)I$ztaD0e0sz65IU4`~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/round_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/round_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..17546646f5b75c8ff9c1f531362cc8f213fa0f7f GIT binary patch literal 1534 zcmbVMJ&e>w6dt5p1P3P}CB-R1Vq_#lq}U#Ny*@lzbK2XzaI3_}>R80lF*}~!wQlV( z_8hx+Rg@G_NRcL0L;-z-l$wGfH8d%pO_?f1+C<5-ch_2^BM2<{=RJS#dq4Bu`>wlt zeQouVRfN!5XQ#af@AJid`a^hL{Oex^uT%Nn^)2+|#f3jW_+Z!!nh5>!!`Z*t3dm>D zojW-~XFn?LQ|PCM>j=IZe-zr z?zKOky93GBMoOjBG$)gZF{v3c8=98qc_y(<+tvZ0=SPWRQ$5Kq%}C}nZISaVN>wBi zT+p(wImtg=G7xR1gs;KrSvslf~C5 zIC=xrc3y)*>x4|Pw}L}X2QrHpBpk(TD9kh&YPc#RZOO6Bz%fKuTh@14t!^d<(HMRd zbA&tFE!Xl~SGNtT3^xd9C&?8{xahQf4T@t#QAqiQaQbe&rdu{6`oMKO-D4nn8?{>B zX8ro0&KCA<$q$PbSlEZ}Xn!M%U>4cz-r(yi-ypIT{ru?h z;C|p_Q{?A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/screw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/screw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc8446a4d0a8c80df030fd29f045dc00288d789d GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgNLV!V~BJ){$>*}Y`3FwNeOkik#`ch1yZODK_D)76={pxC VIk%szoCGwJ!PC{xWt~$(69DhGHlqLl literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/spring_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/spring_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8218e4e9d8be09d0d6d11c8a485033c113e96c GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p?vK$y{C-$S4zgQcg7V~B-+@&XY9r%av;7cP8|KXrt`!E%S4 z2=j+bC$HHuFYb&y1_lfad^dUc4se=p1RB8L>FVdQ&MBb@027rb A#{d8T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/stick_long_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/stick_long_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eb4da2401822a1ea8e09dfcf64c25eb6f29c85 GIT binary patch literal 1525 zcmbVM%Wl&^6g3jhR+W(0l!stsHXvbp?ARe0#h?%e8iY$#f+#DPdM1h0*kkNzlXeLU z#ELbDF94|$YZiO~d<7d;EZ8E!wUb&wDj*tZV&CgC=f3ZYmE~Itb7$rhMOo-9d8_a| znV;iF;s3(-pA;U4vejERl-!#{`pu%E z9JwEM*W{XihXf+hDHH2lA4dtG6{T@~oX}u{OSI1WVeG2kK73SB$XxY-<6}Q*@j zlk$5z%iUmSBd9a=`n83*#+U#@#3e=JXc%W??5YJZf%jZ(sHlL*4OeaE7SWo&f?6Ww zsH$Tvz}P}p>$+LB?JB;4ENo!|JBDd#W|d%@m{-yCr-C_z8Y%0MRqy8197wJ@kTM~L zF&d5ZQAHPN-!SX-x`8djvNS+w*>)`HSc|iZ6Ot*7$Fm>}6B&va<+OBNY)V%Jk0+r- zNy!~&(|keZj4@3NQ^$E|1&{?LF4;_ng$FD!_>f0DmKk8p5}OQ!6xl%hfx7(sn*m6% z@0T|A^(Bf*6PavpK^W7l?2FF2+X**Tc_uc~fVa26&5L<732CLAN|APj815BpWzS_~ znYx88JqTkaM%m?=3*4iUyDC)A)Uc!BTGy-)(;`+ygBoHyf%<}lz3qLWHgW9VpwK#u zO8QSQ3rJ6-5ru%mi1xXW#C;W&X(TN%6e$=6?<%wUPOG(&ie5N`5BVISPP(#1e z>1N@s?~_iPNg4;dgBwyH+!4;IJMTDk?@i z5p3oyuy>#R=l#2B2(w6s2j(e8CZC_i#G$1ygW_(N>ggcd<4rnrCw3OUedQI$ gbDk;f*QXa3m3J?0e`yYOzva8P(_Z#=Z#;hb3x|Kg&Hw-a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/stick_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/stick_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfb966fa6193b40f1da1265fbec39b5a105bae7 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXy1;uxY4TzldqBZC14ljF<%FDtt34t2{OyeaR}?Z{Ul?82X79wJ_%?!z8nT_C+C h?8e&(=G(XrFqchWxFfrNUJTF>22WQ%mvv4FO#oabHD3S# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_buzz_saw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_buzz_saw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec6c9530597c03f94819f41e5ff7bb09226f40 GIT binary patch literal 569 zcmV-90>=G`P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00006P)t-sfPjDi008G`tG)mL00MMUPE-E? z<+m_O00009a7bBm000XR000XR0j(pwbpQYWJ4r-AR47wpU_=89P>KP{01JRPU=c6} z%!UJ)3Y-EMS{T6)Du)ol5FpJ^bO99CLc9R;9Kv@n0XP5vLht~6uebPu00000NkvXX Hu0mjffWz+J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_chainsaw_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_chainsaw_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1dcb11a1553ac4b48904c16b5e438962186ce1 GIT binary patch literal 556 zcmV+{0@MA8P)4Tx04UFukv&MmKpe$iQ>A`X9PFUtkfG{gK~%(1t5Adrp;l;o12rOi)O(glehxvqHp#yRJ*z%xT;GBHmaA{KK^tTZvpn;P*Haah%K$`?`| ztDLtuYsE6F-;=*En9*03xlVHkF)U&U5=1B{qktl8L}=AXv5=tsXbbzBx-kgEVj zjs=vUL3aJ%fAG6oD?2&iB?Y5E`-|gz3AEysMlDdlD00)P_ zNRG1CTfDoYxwk*h)cgAZMlEucH!JBP00009a7bBm000XQ000XQ0h0Lxr2qf`PDw;T zR5(v#WFQeVG&KB2Vly(LO5+E}nqhzmT>uwA*38Vp3>PQL1=wtc0fGkL(@Zc72x(>@ u*99=m48$0~fF4Tx04UFukvT{MK^TRLL`5t$3L+?ks9@B>-HnMtb`y3J zY%B#^!NQ~QDr~H^wXhWg!2`t3&PvfnWc?=zBnS~480O>6yvNKN@E@j4%dP1J%g#Bm z@rX7TpV#VMXrzq*A;P-pW=EpYNve*|JA7)r4XZ5vH<}a6t_eO(c-YK3IpHPY!L?jg z@vd;tT+tK4XTm*>Tu}Hy=|+)X6{ia9SD8U)CN?S@6xLD|Y*eth;#k51!kr1rmVEzQ zkrRs76VS3;w9M3~{Yu zieron7J9*t`h(xyy2<{&Vp3BCYM(vty$kBL;d{&TzK%Ta`xpXGaA}wQnL`-*5Phqx zbsj*=2Ap4&HDd=ZHX-zw)g8Sc1!Ve@Nq9SzZ;C_f4Kyqidn@g8at|}o)#Nqo?L&7; zvKOnoyS}owKhKo<`vH24a;gjO)!hI9010qNS#tmY3l9JQ3l9O3`2(c@002x$L_t(I zPwkIE4!|G`!(3jTpN~@|s9-G|r}>&VYK==IJpdMi3>TfFfhbF|(m)iQ(!iTc_Ch8D qv^km?i#yT+;gZVelHEH$pP&P1799v^(wYhY0000NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iPKL|5U`pLW$ zD5&k};uxY4oSfjo%oD*P5x{bg>4cJkSr^BQP93I1#ZCuF4#5(s)z&W*7#M047~Y$@ S>tqA9F?hQAxvXS| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_wrench_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/tool_head_wrench_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bc712a56458baa8f588696e753a02a1d1e598c2a GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`kNVGw3Kp1&dm zC}`yA;uxY4oSfjo%;Vu>Ag##oa4|jNeQJ7#4LrH_hE8cG>y4VpU`rgW+_==fwa ZG88#5JoG-Dwg;%2!PC{xWt~$(69A&aFb@C# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/turbine_blade_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/turbine_blade_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..bee28ea611efdaa9e26a4c3d63e9c47bd88bdad8 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`j)FbFd;%$g$s z6twkpaSYK2jy>-v#Gt_86u9UAQfXho#H+u%X9<}7h-8{@qhU^q(E)>P8_F-pUi)kI mv)StKM;5Dubqag-ueD8Gz_9-uQ`st@K@6U*elF{r5}E+3a638x literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/wood/wire_fine_mask.png b/src/main/resources/assets/gregtech/textures/items/material_sets/wood/wire_fine_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..71205f27c6f751283a131849b4a0dcaa52ac760f GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}E0G|-ohK2?p^LfVVeL#w-B*-uLKf}}Q23|lOXMsm#F#`iP9|$u#?0X2* z%wXf`;uxY4oZA=3#bChUboZ~m?KCOF&x_wQik=f*#kZSbMku>z!@SJ}%tu-0EW7F8 lQj|HzbYbeB>RPP>tjWF%dsW$tQ-S6%c)I$ztaD0e0stUPHt_%e literal 0 HcmV?d00001 From f095aaeecea4727ee6e66a56c6141db30dbb5333 Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:07:43 +0000 Subject: [PATCH 160/168] Fix Dependencies Post Merge --- dependencies.gradle | 3 +-- src/main/java/gregtech/GregTechMod.java | 2 ++ src/main/java/gregtech/api/unification/material/Material.java | 1 + .../java/gregtech/client/utils/BloomEffectVintagiumUtil.java | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index cd9463ed21f..17ab5a973d1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -62,8 +62,7 @@ dependencies { // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - - runtimeOnlyNonPublishable rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 46ab41d0928..a7cc4eada78 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -7,7 +7,9 @@ import gregtech.api.items.metaitem.MetaItem; import gregtech.api.modules.ModuleContainerRegistryEvent; import gregtech.api.persistence.PersistentData; +import gregtech.api.util.Mods; import gregtech.client.utils.BloomEffectUtil; +import gregtech.client.utils.BloomEffectVintagiumUtil; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 9f3c9630a0a..b2f5976bd71 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -11,6 +11,7 @@ import gregtech.api.unification.material.info.MaterialFlags; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.CosmicProperty; import gregtech.api.unification.material.properties.DustProperty; import gregtech.api.unification.material.properties.FluidPipeProperties; import gregtech.api.unification.material.properties.FluidProperty; diff --git a/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java index 68bd1469c38..600a328b915 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java @@ -19,4 +19,6 @@ public class BloomEffectVintagiumUtil { public static BlockRenderPass getBloomPass() { return Objects.requireNonNull(BlockRenderPass.valueOf("BLOOM"), "Bloom effect is not initialized yet"); } + + public static void init() {} } From 9b8ec4e02bc9b941e7f7881e5e7b7d08a4a4108c Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:16:00 +0000 Subject: [PATCH 161/168] Update MetaItem.java --- src/main/java/gregtech/api/items/metaitem/MetaItem.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index f7d03792908..2e08f0ed923 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -806,6 +806,7 @@ public ModularUI createUI(PlayerInventoryHolder holder, EntityPlayer entityPlaye public void renderItemOverlayIntoGUI(@NotNull ItemStack stack, int xPosition, int yPosition) { ToolChargeBarRenderer.renderBarsItem(this, stack, xPosition, yPosition); } + @Override @SideOnly(Side.CLIENT) public boolean shouldDrawHalo(ItemStack stack) { T metaValueItem = getItem(stack); From 00640d6dfbf23d6869d87950b19fdeb112b88187 Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Fri, 20 Dec 2024 09:33:15 +0000 Subject: [PATCH 162/168] Update CosmicItemRenderer.java Cleaner Code + Credits to Avaritia Owners --- .../renderer/item/CosmicItemRenderer.java | 39 +++++-------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java index 85246cf662a..f4dce417740 100644 --- a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java +++ b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java @@ -47,8 +47,14 @@ modid = Mods.Names.AVARITIA, iface = "morph.avaritia.client.render.shader.CosmicShaderHelper") public class CosmicItemRenderer extends WrappedItemRenderer { + private static final HashMap spriteQuadCache = new HashMap(); - private Random randy = new Random(); + + private Random random = new Random(); + + // Had to use Avaritia's render and modify it to allow for Cosmic Render With Halo and Pulse Effect + // I Didn't create these methods here, these are Avaritia's (Some of which have been cleaned/modified) + // Avalible here -> https://www.curseforge.com/minecraft/mc-mods/avaritia-1-10 public CosmicItemRenderer(IModelState state, IBakedModel model) { super(state, model); @@ -59,10 +65,8 @@ public CosmicItemRenderer(IModelState state, WrappedItemRenderer.IWrappedModelGe } public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType transformType) { - RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); Tessellator tess = Tessellator.getInstance(); BufferBuilder buffer = tess.getBuffer(); - this.processLightLevel(transformType); if (stack.getItem() instanceof IHaloRenderItem && transformType == ItemCameraTransforms.TransformType.GUI) { IHaloRenderItem hri = (IHaloRenderItem)stack.getItem(); GlStateManager.pushMatrix(); @@ -90,7 +94,7 @@ public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType trans if (hri.shouldDrawPulse(stack)) { GlStateManager.pushMatrix(); - double scale = this.randy.nextDouble() * 0.15 + 0.95; + double scale = this.random.nextDouble() * 0.15 + 0.95; double trans = (1.0 - scale) / 2.0; GlStateManager.translate(trans, trans, 0.0); GlStateManager.scale(scale, scale, 1.0001); @@ -113,8 +117,8 @@ public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType trans } else { this.renderSimple(stack, this.renderEntity); } - } + protected void renderSimple(ItemStack stack, EntityLivingBase player) { GlStateManager.pushMatrix(); GlStateManager.enableBlend(); @@ -179,29 +183,4 @@ protected void renderInventory(ItemStack stack, EntityLivingBase player) { GlStateManager.disableBlend(); GlStateManager.popMatrix(); } - protected void processLightLevel(ItemCameraTransforms.TransformType transformType) { - switch (transformType) { - case GROUND: - if (this.entityPos != null) { - CosmicShaderHelper.setLightFromLocation(this.world, this.entityPos); - return; - } - break; - case THIRD_PERSON_LEFT_HAND: - case THIRD_PERSON_RIGHT_HAND: - case FIRST_PERSON_LEFT_HAND: - case FIRST_PERSON_RIGHT_HAND: - case HEAD: - if (this.renderEntity != null) { - CosmicShaderHelper.setLightFromLocation(this.world, this.entityPos); - return; - } - break; - case GUI: - CosmicShaderHelper.setLightLevel(1.2F); - return; - } - - CosmicShaderHelper.setLightLevel(1.0F); - } } From 2bbcd6e827a74163f067b45e8862ca2fd077f798 Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sat, 21 Dec 2024 15:18:36 +0000 Subject: [PATCH 163/168] Added Api Files from Avaritia added Api Files from Avaritia to fix an issue caused by them not being there --- .../morph/avaritia/api/ICosmicRenderItem.java | 36 +++++++++++++++++++ .../morph/avaritia/api/IHaloRenderItem.java | 25 +++++++++++++ .../api/registration/IModelRegister.java | 17 +++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/api/java/morph/avaritia/api/ICosmicRenderItem.java create mode 100644 src/api/java/morph/avaritia/api/IHaloRenderItem.java create mode 100644 src/api/java/morph/avaritia/api/registration/IModelRegister.java diff --git a/src/api/java/morph/avaritia/api/ICosmicRenderItem.java b/src/api/java/morph/avaritia/api/ICosmicRenderItem.java new file mode 100644 index 00000000000..9e8373655d7 --- /dev/null +++ b/src/api/java/morph/avaritia/api/ICosmicRenderItem.java @@ -0,0 +1,36 @@ +package morph.avaritia.api; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; + +/** + * Any item implementing this that also binds itself to TODO INPUT MODEL NAME HERE. + * Will automatically have the cosmic shader applied to the mask with the given opacity. + */ +public interface ICosmicRenderItem { + + /** + * The mask where the cosmic overlay will be. + * + * @param stack The stack being rendered. + * @param player The entity holding the item, May be null, If null assume either inventory, or ground. + * @return The masked area where the cosmic overlay will be. + */ + @SideOnly (Side.CLIENT) + TextureAtlasSprite getMaskTexture(ItemStack stack, @Nullable EntityLivingBase player); + + /** + * The opacity that the mask overlay will be rendered with. + * + * @param stack The stack being rendered. + * @param player The entity holding the item, May be null, If null assume either inventory, or ground. + * @return The opacity that the mask overlay will be rendered with. + */ + @SideOnly (Side.CLIENT) + float getMaskOpacity(ItemStack stack, @Nullable EntityLivingBase player); +} diff --git a/src/api/java/morph/avaritia/api/IHaloRenderItem.java b/src/api/java/morph/avaritia/api/IHaloRenderItem.java new file mode 100644 index 00000000000..ebc34b4b5d7 --- /dev/null +++ b/src/api/java/morph/avaritia/api/IHaloRenderItem.java @@ -0,0 +1,25 @@ +package morph.avaritia.api; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public interface IHaloRenderItem { + + @SideOnly (Side.CLIENT) + boolean shouldDrawHalo(ItemStack stack); + + @SideOnly (Side.CLIENT) + TextureAtlasSprite getHaloTexture(ItemStack stack); + + @SideOnly (Side.CLIENT) + int getHaloColour(ItemStack stack); + + @SideOnly (Side.CLIENT) + int getHaloSize(ItemStack stack); + + @SideOnly (Side.CLIENT) + boolean shouldDrawPulse(ItemStack stack); + +} diff --git a/src/api/java/morph/avaritia/api/registration/IModelRegister.java b/src/api/java/morph/avaritia/api/registration/IModelRegister.java new file mode 100644 index 00000000000..3c87cd8c76c --- /dev/null +++ b/src/api/java/morph/avaritia/api/registration/IModelRegister.java @@ -0,0 +1,17 @@ +package morph.avaritia.api.registration; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +/** + * Implemented on an item for model registration, completely arbitrary. + */ +public interface IModelRegister { + + /** + * Called when it is time to initialize models in preInit. + */ + @SideOnly (Side.CLIENT) + void registerModels(); + +} From 04f8246f0701d2a1802a3a0e8660055fc7966d6b Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:43:28 +0000 Subject: [PATCH 164/168] SpotlessCheck and SpotlessApply Run ./gradlew :spotlessCheck --warning-mode all --build-cache and ./gradlew :spotlessApply --warning-mode all to fix and clean code --- src/main/java/gregtech/GregTechMod.java | 4 +- .../items/materialitem/MetaPrefixItem.java | 61 +++++---- .../gregtech/api/items/metaitem/MetaItem.java | 122 ++++++++++-------- .../api/unification/material/Material.java | 35 +++-- .../material/properties/CosmicProperty.java | 14 +- .../renderer/item/CosmicItemRenderer.java | 70 +++++----- 6 files changed, 167 insertions(+), 139 deletions(-) diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index a7cc4eada78..72b7f528cdf 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -1,7 +1,5 @@ package gregtech; -import codechicken.lib.texture.TextureUtils; - import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.items.metaitem.MetaItem; @@ -31,6 +29,8 @@ import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; +import codechicken.lib.texture.TextureUtils; + import static gregtech.api.util.Mods.Avaritia; @Mod(modid = GTValues.MODID, diff --git a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java index ad8ed82b3e8..a2fe30037be 100644 --- a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java +++ b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java @@ -1,13 +1,10 @@ package gregtech.api.items.materialitem; -import codechicken.lib.model.ModelRegistryHelper; -import codechicken.lib.util.TransformUtils; - import gregtech.api.GTValues; import gregtech.api.damagesources.DamageSources; import gregtech.api.items.armor.ArmorMetaItem; -import gregtech.api.items.metaitem.StandardMetaItem; import gregtech.api.items.metaitem.MetaItem.MetaValueItem.CosmicTexture; +import gregtech.api.items.metaitem.StandardMetaItem; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; @@ -19,15 +16,9 @@ import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; -import gregtech.common.creativetab.GTCreativeTabs; - import gregtech.api.util.Mods; import gregtech.client.renderer.item.CosmicItemRenderer; - -import morph.avaritia.api.ICosmicRenderItem; -import morph.avaritia.api.IHaloRenderItem; -import morph.avaritia.api.registration.IModelRegister; -import morph.avaritia.init.AvaritiaTextures; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockCauldron; import net.minecraft.block.state.IBlockState; @@ -48,7 +39,13 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import codechicken.lib.model.ModelRegistryHelper; +import codechicken.lib.util.TransformUtils; import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; +import morph.avaritia.api.ICosmicRenderItem; +import morph.avaritia.api.IHaloRenderItem; +import morph.avaritia.api.registration.IModelRegister; +import morph.avaritia.init.AvaritiaTextures; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,19 +54,19 @@ import static gregtech.api.util.Mods.Avaritia; @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.ICosmicRenderItem") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.ICosmicRenderItem") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.IHaloRenderItem") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.IHaloRenderItem") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.registration.IModelRegister") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.registration.IModelRegister") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.init.AvaritiaTextures") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.init.AvaritiaTextures") public class MetaPrefixItem extends StandardMetaItem implements IHaloRenderItem, ICosmicRenderItem, - IModelRegister { + IModelRegister { private final MaterialRegistry registry; private final OrePrefix prefix; @@ -154,10 +151,10 @@ public void registerModels() { ModelBakery.registerItemVariants(this, resourceLocation); alreadyRegistered.put(registrationKey, new ModelResourceLocation(resourceLocation, "inventory")); - if (Avaritia.isModLoaded()) { ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); - IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); + IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, + (modelRegistry) -> modelRegistry.getObject(location)); ModelRegistryHelper.register(location, wrapped); String processedLocation = resourceLocation.toString().replace("gregtech:", "gregtech:items/"); @@ -312,9 +309,9 @@ protected void addMaterialTooltip(@NotNull List lines, @NotNull ItemStac } } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public boolean shouldDrawHalo(ItemStack stack) { - Material material = getMaterial(stack); assert material != null; @@ -327,9 +324,9 @@ public boolean shouldDrawHalo(ItemStack stack) { } } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public TextureAtlasSprite getHaloTexture(ItemStack stack) { - Material material = getMaterial(stack); assert material != null; @@ -342,9 +339,9 @@ public TextureAtlasSprite getHaloTexture(ItemStack stack) { } } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public int getHaloColour(ItemStack stack) { - Material material = getMaterial(stack); assert material != null; @@ -357,9 +354,9 @@ public int getHaloColour(ItemStack stack) { } } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public int getHaloSize(ItemStack stack) { - Material material = getMaterial(stack); assert material != null; @@ -370,10 +367,10 @@ public int getHaloSize(ItemStack stack) { } else { return 0; } - } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public boolean shouldDrawPulse(ItemStack stack) { Material material = getMaterial(stack); assert material != null; diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index 2e08f0ed923..bc10af80e74 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -1,9 +1,5 @@ package gregtech.api.items.metaitem; -import codechicken.lib.model.ModelRegistryHelper; -import codechicken.lib.texture.TextureUtils; -import codechicken.lib.util.TransformUtils; - import gregtech.api.GTValues; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IElectricItem; @@ -41,11 +37,6 @@ import gregtech.common.covers.filter.IFilter; import gregtech.common.creativetab.GTCreativeTabs; -import morph.avaritia.api.ICosmicRenderItem; -import morph.avaritia.api.IHaloRenderItem; -import morph.avaritia.api.registration.IModelRegister; -import morph.avaritia.init.AvaritiaTextures; - import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; @@ -86,6 +77,9 @@ import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.oredict.OreDictionary; +import codechicken.lib.model.ModelRegistryHelper; +import codechicken.lib.texture.TextureUtils; +import codechicken.lib.util.TransformUtils; import com.enderio.core.common.interfaces.IOverlayRenderAware; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; @@ -95,6 +89,10 @@ import it.unimi.dsi.fastutil.shorts.Short2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; +import morph.avaritia.api.ICosmicRenderItem; +import morph.avaritia.api.IHaloRenderItem; +import morph.avaritia.api.registration.IModelRegister; +import morph.avaritia.init.AvaritiaTextures; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -129,23 +127,23 @@ * rechargeable) LV battery with initial capacity 10000 EU */ @Optional.Interface( - modid = Mods.Names.ENDER_CORE, - iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") + modid = Mods.Names.ENDER_CORE, + iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.ICosmicRenderItem") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.ICosmicRenderItem") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.IHaloRenderItem") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.IHaloRenderItem") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.registration.IModelRegister") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.registration.IModelRegister") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.init.AvaritiaTextures") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.init.AvaritiaTextures") public abstract class MetaItem.MetaValueItem> extends Item - implements ItemUIFactory, IOverlayRenderAware, IHaloRenderItem, ICosmicRenderItem, - IModelRegister { + implements ItemUIFactory, IOverlayRenderAware, IHaloRenderItem, ICosmicRenderItem, + IModelRegister { private static final List> META_ITEMS = new ArrayList<>(); @@ -646,7 +644,6 @@ public String getItemStackDisplayName(ItemStack stack) { return super.getItemStackDisplayName(stack); } - @Override @SideOnly(Side.CLIENT) public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn, @NotNull List lines, @@ -807,16 +804,18 @@ public void renderItemOverlayIntoGUI(@NotNull ItemStack stack, int xPosition, in ToolChargeBarRenderer.renderBarsItem(this, stack, xPosition, yPosition); } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public boolean shouldDrawHalo(ItemStack stack) { T metaValueItem = getItem(stack); - if (metaValueItem == null){ + if (metaValueItem == null) { return false; } return metaValueItem.registerHalo(stack); } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public TextureAtlasSprite getHaloTexture(ItemStack stack) { T metaValueItem = getItem(stack); if (metaValueItem.registerHaloTexture(stack) == null) { @@ -825,28 +824,31 @@ public TextureAtlasSprite getHaloTexture(ItemStack stack) { return MetaValueItem.CosmicTexture.haloTextures.get(metaValueItem.registerHaloTexture(stack)); } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public int getHaloColour(ItemStack stack) { T metaValueItem = getItem(stack); - if (metaValueItem == null){ + if (metaValueItem == null) { return 0; } return Integer.decode("0x7F" + metaValueItem.registerHaloColour(stack)); } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public int getHaloSize(ItemStack stack) { T metaValueItem = getItem(stack); - if (metaValueItem == null){ + if (metaValueItem == null) { return 0; } return metaValueItem.registerHaloSize(stack); } - @Override @SideOnly(Side.CLIENT) + @Override + @SideOnly(Side.CLIENT) public boolean shouldDrawPulse(ItemStack stack) { T metaValueItem = getItem(stack); - if (metaValueItem == null){ + if (metaValueItem == null) { return false; } return metaValueItem.registerHaloPulse(stack); @@ -864,7 +866,7 @@ public TextureAtlasSprite getMaskTexture(ItemStack stack, EntityLivingBase playe @SideOnly(Side.CLIENT) public float getMaskOpacity(ItemStack stack, EntityLivingBase player) { T metaValueItem = getItem(stack); - if (metaValueItem == null){ + if (metaValueItem == null) { return 0.0f; } return metaValueItem.registerMaskOpacity(stack); @@ -1003,18 +1005,25 @@ public MetaValueItem addComponents(IItemComponent... stats) { /** * This function requires the latest version of Avaritia to be Installed - * ... + * ... * - * @param shouldDrawHalo enables the Halo effect for a specified MetaItem.
- * @param haloTexture the Halo Texture for a specified MetaItem in the form of a String : Example "halo".
- * @param haloColour the Colour the Halo will have in the form of a Hex String : Example "00FF00" (hex color for green).
- * @param haloSize The size of the halo : Example 10.
+ * @param shouldDrawHalo enables the Halo effect for a specified MetaItem.
+ * @param haloTexture the Halo Texture for a specified MetaItem in the form of a String : Example + * "halo".
+ * @param haloColour the Colour the Halo will have in the form of a Hex String : Example "00FF00" (hex + * color for green).
+ * @param haloSize The size of the halo : Example 10.
* @param shouldDrawPulse Whether the MetaItem will pulse like Avaritia's Infinity Ingot : Example true.
- * @param maskTexture The String Location of the Mask texture the MetaItem will use as a Cosmic Effect : Example "nan".
- * @param maskOpacity The Opacity of the Cosmic Effect, Use in combination with maskTexture : Example 1.0f.
+ * @param maskTexture The String Location of the Mask texture the MetaItem will use as a Cosmic Effect : + * Example "nan".
+ * @param maskOpacity The Opacity of the Cosmic Effect, Use in combination with maskTexture : Example + * 1.0f.
*/ @Optional.Method(modid = Mods.Names.AVARITIA) - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse, String maskTexture, float maskOpacity) { + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, + int haloSize, boolean shouldDrawPulse, String maskTexture, + float maskOpacity) { if (Avaritia.isModLoaded()) { this.drawHalo = shouldDrawHalo; this.haloPath = haloTexture; @@ -1038,7 +1047,8 @@ public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture } @Optional.Method(modid = Mods.Names.AVARITIA) - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, String maskTexture, float maskOpacity) { + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, + int haloSize, String maskTexture, float maskOpacity) { if (Avaritia.isModLoaded()) { this.drawHalo = shouldDrawHalo; this.haloPath = haloTexture; @@ -1061,7 +1071,8 @@ public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture } @Optional.Method(modid = Mods.Names.AVARITIA) - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse) { + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, + int haloSize, boolean shouldDrawPulse) { if (Avaritia.isModLoaded()) { this.drawHalo = shouldDrawHalo; this.haloPath = haloTexture; @@ -1077,7 +1088,8 @@ public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture } @Optional.Method(modid = Mods.Names.AVARITIA) - public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize) { + public MetaValueItem cosmicProperties(boolean shouldDrawHalo, String haloTexture, String haloColour, + int haloSize) { if (Avaritia.isModLoaded()) { this.drawHalo = shouldDrawHalo; this.haloPath = haloTexture; @@ -1112,7 +1124,6 @@ public MetaValueItem cosmicProperties(boolean shouldDrawPulse) { return this; } - protected void addItemComponentsInternal(IItemComponent... stats) { for (IItemComponent itemComponent : stats) { if (itemComponent instanceof IItemNameProvider) { @@ -1324,36 +1335,36 @@ public String toString() { .toString(); } - public boolean registerHalo (ItemStack stack) { + public boolean registerHalo(ItemStack stack) { return drawHalo; } public String registerHaloTexture(ItemStack stack) { return haloPath; - } - public String registerHaloColour (ItemStack stack) { + public String registerHaloColour(ItemStack stack) { return haloColour; } - public int registerHaloSize (ItemStack stack) { + public int registerHaloSize(ItemStack stack) { return haloSize; } - public boolean registerHaloPulse (ItemStack stack) { + public boolean registerHaloPulse(ItemStack stack) { return haloPulse; } - public String registerMaskTexture (ItemStack stack) { + public String registerMaskTexture(ItemStack stack) { return maskPath; } - public float registerMaskOpacity (ItemStack stack) { + public float registerMaskOpacity(ItemStack stack) { return maskOpacity; } public static class CosmicTexture implements TextureUtils.IIconRegister { + public static Map haloTextures = new HashMap<>(); public static Map maskTextures = new HashMap<>(); public static Map specialMaskTextures = new HashMap<>(); @@ -1376,15 +1387,18 @@ public static void registerSpecialMaskIcon(String stack, String path) { @Override public void registerIcons(TextureMap textureMap) { haloPath.forEach(halo -> { - haloTextures.put(halo, textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/halo/" + halo))); + haloTextures.put(halo, + textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/halo/" + halo))); }); cosmicPath.forEach(mask -> { - maskTextures.put(mask, textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/" + mask))); + maskTextures.put(mask, + textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/" + mask))); }); specialCosmicPath.forEach((key, value) -> { specialMaskTextures.put(key, textureMap.registerSprite(new ResourceLocation(value))); - specialMaskTextures.put("fallback", textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/fallback"))); + specialMaskTextures.put("fallback", + textureMap.registerSprite(new ResourceLocation("gregtech:items/cosmic/mask/fallback"))); }); } } diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index b2f5976bd71..9ec9b93f41b 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -39,13 +39,11 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.common.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import crafttweaker.annotations.ZenRegister; - -import net.minecraftforge.fml.common.Optional; - import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -835,18 +833,26 @@ public Builder polymer(int harvestLevel) { /** * Add a {@link CosmicProperty} to this Material.
* This function requires the latest version of Avaritia to be Installed - * ... - * @param shouldDrawHalo enables the Halo effect for a specified Material.
- * @param haloTexture the Halo Texture for a specific Material in the form of a String : Example "halo".
- * @param haloColour the Colour the Halo will have in the form of a Hex String : Example "00FF00" (hex color for green).
- * @param haloSize The size of the halo : Example 10.
- * @param shouldDrawPulse If the Material Item will pulse like Avaritia's Infinity Ingot : Example true.
+ * ... + * + * @param shouldDrawHalo enables the Halo effect for a specified Material.
+ * @param haloTexture the Halo Texture for a specific Material in the form of a String : Example + * "halo".
+ * @param haloColour the Colour the Halo will have in the form of a Hex String : Example "00FF00" (hex + * color for green).
+ * @param haloSize The size of the halo : Example 10.
+ * @param shouldDrawPulse If the Material Item will pulse like Avaritia's Infinity Ingot : Example true.
* @param shouldDrawCosmic If the Material Item will have Avaritia's Cosmic Effect : Example true.
- * All the locations for these are autogenerated and follow the same path as the MaterialIconSet the material uses: Example "gregtech:textures/items/material_sets/dull/dust_mask - * @param maskOpacity The Opacity of the Cosmic Effect, Use in combination with shouldDrawCosmic : Example 1.0f.
+ * All the locations for these are autogenerated and follow the same path as the + * MaterialIconSet the material uses: Example + * "gregtech:textures/items/material_sets/dull/dust_mask + * @param maskOpacity The Opacity of the Cosmic Effect, Use in combination with shouldDrawCosmic : Example + * 1.0f.
*/ @Optional.Method(modid = Mods.Names.AVARITIA) - public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse, boolean shouldDrawCosmic, Float maskOpacity) { + public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, + boolean shouldDrawPulse, boolean shouldDrawCosmic, Float maskOpacity) { if (Avaritia.isModLoaded()) { properties.setProperty(PropertyKey.COSMIC, new CosmicProperty(shouldDrawHalo, haloTexture, haloColour, haloSize, shouldDrawPulse, @@ -856,7 +862,8 @@ public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloCol } @Optional.Method(modid = Mods.Names.AVARITIA) - public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse) { + public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, + boolean shouldDrawPulse) { if (Avaritia.isModLoaded()) { properties.setProperty(PropertyKey.COSMIC, new CosmicProperty(shouldDrawHalo, haloTexture, haloColour, haloSize, shouldDrawPulse)); @@ -874,7 +881,7 @@ public Builder cosmic(boolean shouldDrawHalo, String haloTexture, String haloCol } @Optional.Method(modid = Mods.Names.AVARITIA) - public Builder cosmic( boolean shouldDrawCosmic, Float maskOpacity) { + public Builder cosmic(boolean shouldDrawCosmic, Float maskOpacity) { if (Avaritia.isModLoaded()) { properties.setProperty(PropertyKey.COSMIC, new CosmicProperty(shouldDrawCosmic, maskOpacity)); } diff --git a/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java b/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java index 08b0d09dc26..077386232a4 100644 --- a/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/CosmicProperty.java @@ -56,7 +56,8 @@ public class CosmicProperty implements IMaterialProperty { */ private Float maskOpacity; - public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse, boolean shouldDrawCosmic, Float maskOpacity) { + public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, + boolean shouldDrawPulse, boolean shouldDrawCosmic, Float maskOpacity) { if (Avaritia.isModLoaded()) { this.shouldDrawHalo = shouldDrawHalo; this.haloTexture = haloTexture; @@ -69,7 +70,8 @@ public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloCol } } - public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, boolean shouldDrawPulse) { + public CosmicProperty(boolean shouldDrawHalo, String haloTexture, String haloColour, int haloSize, + boolean shouldDrawPulse) { if (Avaritia.isModLoaded()) { this.shouldDrawHalo = shouldDrawHalo; this.haloTexture = haloTexture; @@ -95,7 +97,6 @@ public CosmicProperty(boolean shouldDrawCosmic, Float maskOpacity) { this.shouldDrawCosmic = shouldDrawCosmic; this.maskOpacity = maskOpacity; } - } public CosmicProperty(boolean shouldDrawPulse) { @@ -127,9 +128,11 @@ public boolean getHaloPulse() { public boolean shouldDrawCosmic() { return shouldDrawCosmic; } + public Float getMaskOpacity() { return maskOpacity; } + @Override public void verifyProperty(MaterialProperties properties) { properties.ensureSet(PropertyKey.DUST, true); @@ -156,22 +159,27 @@ public Builder haloTexture(String haloTexture) { this.haloTexture = haloTexture; return this; } + public Builder haloColour(String haloColour) { this.haloColour = haloColour; return this; } + public Builder haloSize(int haloSize) { this.haloSize = haloSize; return this; } + public Builder shouldDrawPulse(boolean shouldDrawPulse) { this.shouldDrawPulse = shouldDrawPulse; return this; } + public Builder shouldDrawCosmic(boolean shouldDrawCosmic) { this.shouldDrawCosmic = shouldDrawCosmic; return this; } + public Builder maskOpacity(Float maskOpacity) { this.maskOpacity = maskOpacity; return this; diff --git a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java index f4dce417740..2162f02fce8 100644 --- a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java +++ b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java @@ -1,23 +1,9 @@ package gregtech.client.renderer.item; -import codechicken.lib.colour.Colour; -import codechicken.lib.model.ItemQuadBakery; -import codechicken.lib.model.bakedmodels.ModelProperties; -import codechicken.lib.model.bakedmodels.PerspectiveAwareBakedModel; -import codechicken.lib.util.TransformUtils; -import com.google.common.collect.ImmutableList; - import gregtech.api.util.Mods; -import morph.avaritia.api.ICosmicRenderItem; -import morph.avaritia.api.IHaloRenderItem; -import morph.avaritia.client.render.item.WrappedItemRenderer; -import morph.avaritia.client.render.shader.CosmicShaderHelper; - -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderItem; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; @@ -30,22 +16,33 @@ import net.minecraftforge.common.model.IModelState; import net.minecraftforge.fml.common.Optional; +import codechicken.lib.colour.Colour; +import codechicken.lib.model.ItemQuadBakery; +import codechicken.lib.model.bakedmodels.ModelProperties; +import codechicken.lib.model.bakedmodels.PerspectiveAwareBakedModel; +import codechicken.lib.util.TransformUtils; +import com.google.common.collect.ImmutableList; +import morph.avaritia.api.ICosmicRenderItem; +import morph.avaritia.api.IHaloRenderItem; +import morph.avaritia.client.render.item.WrappedItemRenderer; +import morph.avaritia.client.render.shader.CosmicShaderHelper; + import java.util.HashMap; import java.util.List; import java.util.Random; @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.ICosmicRenderItem") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.ICosmicRenderItem") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.IHaloRenderItem") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.api.IHaloRenderItem") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.client.render.item.WrappedItemRenderer") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.client.render.item.WrappedItemRenderer") @Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.client.render.shader.CosmicShaderHelper") + modid = Mods.Names.AVARITIA, + iface = "morph.avaritia.client.render.shader.CosmicShaderHelper") public class CosmicItemRenderer extends WrappedItemRenderer { private static final HashMap spriteQuadCache = new HashMap(); @@ -68,16 +65,17 @@ public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType trans Tessellator tess = Tessellator.getInstance(); BufferBuilder buffer = tess.getBuffer(); if (stack.getItem() instanceof IHaloRenderItem && transformType == ItemCameraTransforms.TransformType.GUI) { - IHaloRenderItem hri = (IHaloRenderItem)stack.getItem(); + IHaloRenderItem hri = (IHaloRenderItem) stack.getItem(); GlStateManager.pushMatrix(); GlStateManager.enableBlend(); GlStateManager.disableDepth(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.disableAlpha(); if (hri.shouldDrawHalo(stack)) { Colour.glColourARGB(hri.getHaloColour(stack)); TextureAtlasSprite sprite = hri.getHaloTexture(stack); - double spread = (double)hri.getHaloSize(stack) / 16.0; + double spread = (double) hri.getHaloSize(stack) / 16.0; double min = 0.0 - spread; double max = 1.0 + spread; float minU = sprite.getMinU(); @@ -85,10 +83,10 @@ public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType trans float minV = sprite.getMinV(); float maxV = sprite.getMaxV(); buffer.begin(7, DefaultVertexFormats.POSITION_TEX); - buffer.pos(max, max, 0.0).tex((double)maxU, (double)minV).endVertex(); - buffer.pos(min, max, 0.0).tex((double)minU, (double)minV).endVertex(); - buffer.pos(min, min, 0.0).tex((double)minU, (double)maxV).endVertex(); - buffer.pos(max, min, 0.0).tex((double)maxU, (double)maxV).endVertex(); + buffer.pos(max, max, 0.0).tex((double) maxU, (double) minV).endVertex(); + buffer.pos(min, max, 0.0).tex((double) minU, (double) minV).endVertex(); + buffer.pos(min, min, 0.0).tex((double) minU, (double) maxV).endVertex(); + buffer.pos(max, min, 0.0).tex((double) maxU, (double) maxV).endVertex(); tess.draw(); } @@ -128,11 +126,12 @@ protected void renderSimple(ItemStack stack, EntityLivingBase player) { IBakedModel model = this.wrapped.getOverrides().handleItemState(this.wrapped, stack, world, player); renderModel(model, stack); if (stack.getItem() instanceof ICosmicRenderItem) { - ICosmicRenderItem cri = (ICosmicRenderItem)stack.getItem(); + ICosmicRenderItem cri = (ICosmicRenderItem) stack.getItem(); GlStateManager.disableAlpha(); GlStateManager.depthFunc(514); TextureAtlasSprite cosmicSprite = cri.getMaskTexture(stack, player); - IBakedModel cosmicModel = (IBakedModel)spriteQuadCache.computeIfAbsent(cosmicSprite, CosmicItemRenderer::computeModel); + IBakedModel cosmicModel = (IBakedModel) spriteQuadCache.computeIfAbsent(cosmicSprite, + CosmicItemRenderer::computeModel); CosmicShaderHelper.cosmicOpacity = cri.getMaskOpacity(stack, player); CosmicShaderHelper.useShader(); renderModel(cosmicModel, stack); @@ -144,6 +143,7 @@ protected void renderSimple(ItemStack stack, EntityLivingBase player) { GlStateManager.disableBlend(); GlStateManager.popMatrix(); } + private static IBakedModel computeModel(TextureAtlasSprite sprite) { List quads = ItemQuadBakery.bakeItem(ImmutableList.of(sprite)); return new PerspectiveAwareBakedModel(quads, TransformUtils.DEFAULT_ITEM, new ModelProperties(true, false)); @@ -159,14 +159,16 @@ protected void renderInventory(ItemStack stack, EntityLivingBase player) { IBakedModel model = this.wrapped.getOverrides().handleItemState(this.wrapped, stack, world, player); renderModel(model, stack); if (stack.getItem() instanceof ICosmicRenderItem) { - ICosmicRenderItem cri = (ICosmicRenderItem)stack.getItem(); + ICosmicRenderItem cri = (ICosmicRenderItem) stack.getItem(); GlStateManager.pushMatrix(); GlStateManager.enableBlend(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.disableAlpha(); GlStateManager.disableDepth(); TextureAtlasSprite sprite = cri.getMaskTexture(stack, player); - IBakedModel cosmicModel = (IBakedModel)spriteQuadCache.computeIfAbsent(sprite, CosmicItemRenderer::computeModel); + IBakedModel cosmicModel = (IBakedModel) spriteQuadCache.computeIfAbsent(sprite, + CosmicItemRenderer::computeModel); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); CosmicShaderHelper.cosmicOpacity = cri.getMaskOpacity(stack, player); CosmicShaderHelper.inventoryRender = true; From ac70ac17ad52908e77810c5e24da0fec1a8b56a0 Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sat, 21 Dec 2024 17:17:28 +0000 Subject: [PATCH 165/168] Update CosmicItemRenderer.java --- .../java/gregtech/client/renderer/item/CosmicItemRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java index 2162f02fce8..d021a7bbd9a 100644 --- a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java +++ b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java @@ -51,7 +51,7 @@ public class CosmicItemRenderer extends WrappedItemRenderer { // Had to use Avaritia's render and modify it to allow for Cosmic Render With Halo and Pulse Effect // I Didn't create these methods here, these are Avaritia's (Some of which have been cleaned/modified) - // Avalible here -> https://www.curseforge.com/minecraft/mc-mods/avaritia-1-10 + // Available here -> https://github.com/Morpheus1101/Avaritia public CosmicItemRenderer(IModelState state, IBakedModel model) { super(state, model); From 14abcab45a6d68ba0b53e7b44b6ff55a871e0fde Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sun, 22 Dec 2024 10:13:33 +0000 Subject: [PATCH 166/168] Create permission5.png I have received permission from Morpheus1101 to use some of Avaritia's code for this new patch. Permission5 is what they said. --- permission5.png | Bin 0 -> 81965 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 permission5.png diff --git a/permission5.png b/permission5.png new file mode 100644 index 0000000000000000000000000000000000000000..8a9bbeaa77d7796dee5a6b50f3c13e1bed11f3d1 GIT binary patch literal 81965 zcmeFZ^;cZcvpq-@f&{nVgg`=YNaGMBxVsbF-95nx79dy}=->{)9fAiB?hxE*+#2XP zdGCGReCHpSH9yQokWvgNDnT-3fa6t`DaA5AP51Z>6{&WplU`Tu|QzX#|4wP9jPtz+dJ zdJx%dPXFMj>E*bYX&RX*S|<+2Oj_FG{}}3%upkp3BrbLH)4&FM0?HLdoJ@qB7s*Mz z!SjkiqN&((DU(V;B6-GF(^b}TB?s0edOm{xCiQ=B0q$T1)Cpi`oKMo3(~5#)W4&fg zkS|fK!o^O{woaciv|n#{RMWL3#QHBR&dUW%VNRKChNtLw@WZe z^*fl~A?aqY?qvBJ!oNum6A8eCEqz3*7x1$$fdRhU2A}9#Yw~c2{qn_F&Tj|KnsIf# z9RZ6K@)%gCy1yrr%Nt0M<`!jq71Y)CR78-*_pB}U;iHGC;}RUZhY7e>T8(FAXJ^$@ zkfG6+k}l59eEj?e`6~A%sE;vO*r**hiW1Ap#!6(hdt;G$y1F(MIw`64q_F}wzrnNm zp7iy8!Fl5H0)?ByYOKrS9s#4^uY=!Nj~p)Y3tz9Vy|bA#@^(H598~XfsnEzZoX(Hhix9|ZKEKe7@ex6e9@qFgcv?=x z87)lG<qa^)dHI)On^K~}NbsX4FK zeI%m=jiy1sb9@U%A$&0|jJ*EhH@rOl6>>#SqVZ!Fo6BW0>VUtt<+x{$HZFztfG8VX zlQb&NPPc8Q{`eHxd^fBZ7GS)I5}>X;stiW1xw+Y6=^AbU^S=NludA(P=UjYY%8{x< z8j2I&D1(oWmy!_R1D=r#QnFm_Wul@IkY0$;X|V1F;{o%(vD$omB>Btf7EG`vatRi|AMumeRWU0vvq z`9ObvmTC<7bzyUJ8t)d|elMT& z56cXaaFcju%XKL#m6OtIedWimU$=pQonZlu@yS~|D-DMkZZ4aHM&`gV+3?;6@5R%rDx=PuR89*vhFhmwU%zf+Cq=~(X0is90BTlNMF@0p!Zne1 zWh#M#vAeUgsJr)EMaKJKtDq{k07)P$lbC##J=S>Y?4n4hUyNC${j- zXlN|NVeWRWxLojVg44^(E7Qm*R`|Z)4k7x_6dUWC7uwY>9qL6NFo^LW^Ec;It=BzJ zD7T&eX*9R6UR%3u?O-Y=;*wVzL_qs8-BqK%tYwXj=E(aXi69YLqLFk?+1EJK!9*;2 zI205g;!PC}Hym28llrwaG^S?$nAYgX%E+Y3UQ_V4wFjgKvoyPbNihI7I9`op-8tvu zW9MKT8(Ms1QE_8>Csv_liy5?weG|6A6KXU#p^Gvb3`(H3EQ`c`&zAi8H zWOL)^iJ9@xLwaK<5GRp#k463@paouC1yE55`|Huh<=#F(xt@RHpP2`<|Y2 zqheE5!zRYYPTCPv8U>TiA;u@)q%RWe%f8ReQ3VLxE_xtX4C~MIxR31BCe*>jnKglql!BthapfThGgBq00+i)7HRr|UZJAZ-n$smsTdi+Y zEpC^gcd@KTO-{~14(MQM8_Xdi?O{Usgv-Fh#Ps^LRJPTCKmd)fup#wdhI~3s&IfF- z@!|&Qf@}R64%*<&1L3}RJE?LK&%+K5SBBG2(%6hvyMF!n)p&DLe&Iiq7K$TkiKwNB z6}bJaY3SFTcBJ{vXjNR;aJi_zCLyEq_r!BHL-X)ek|T zVZ=d-+o83;%=-5^3d&#ehTNBWOG`qLM6CKgNHH6D!1l!}57f6e4$OmV$32P}wYwRp zQ-ViFV}v$pD{-!Sk66MIAm;o1HJ7D6e^(N1;AFyHFJig>)+-oSte0&RYc8L@|HxK_ z{n1!vw-J@H)n}5=16z?#nVMj!!u1+_Ldogw3tQ+snVep(uB|=sY}T$aXECfD92prg zt{~_27GSX8IVcN2ZM%Nza}=)q;CE1%S?$LSoz02QMjJXzr{(8b4}Te|TJOFtEUvE1 zs?5!O#m!LHq)SCg>a~ac8Py*5X;9pd`IDy|7F^!Pp1zUYb7fW*3MdNU;b^^10^AJK ztxxI%vqxtp-vvWcSHRWJZIIsTjEQUv3*NM}9qgC`eSNhKaP#tlg6&>0;pbfEbuaNE zTAG`qdNLa4bT+wwuhj|sCzYXKV?3LGhK89TU?<_BsHl8z7OW(vm-U_+EaQsjZhlWa zjVrVg@<+~&F5?pxuD2OFZSX1w7uklJk-Y_N_dYMx4#0j*hI2i`I=8X~6mF4oi+ec*z!M9b~w zRnqZYP6BN|{?1xtz}ZRmiLbh+hMc_|-Q5op6a}MkWMpJ~k3+Uvngy^aZ;lV@e0*BZ zpsxwgrpojM&H7Ebxw(UtBqe)~*M#%)@}8oij>=|7$;fLrd846|aVEkG{IY+Ap-Y3cvjg+dUFH{~cuE$2C`|y!DR$LfE^>4X5g1I2WmpU*>5# z(c0P?%=6^<@GygW*|VywHAaS9*#GvxgXtux&yi@r7LuHp7;xN8{O*x0Z%uGkR#x5e zjpE1me@|J3;2Um&j51bsc2$N#ojKC@TdZkt=2Pox&F|f`@ART zR6@uysPM<&RKjdlI-ZPMD0sNIbviA4WYZgNX*TIqK+xmi#>L6Pb?{yg^=~-aL3CYY zPwNZ=JZ{dc_#OqRF@kv~Z>$352{jm_sG8Co-@(C}p#1{R z=l370W{Vi#*4f@=fqS<;FLE;B)Dx!-q%JBd_JA*>Cnrme@JHF@$$jT?YVUXw^zC)3 zocrbC!0PH+i0A|9c#3oi3q{ysjScsjgfQ=`>kEE+&EFeLL<5#wMFW$<$lFuF%cb#! zg%j|UqqDbCZr2Bu7UV^qD8 zn05IamKN4}1D5KKT@YT9u?hiy+fjF|_YA!@2m`72xhZKT#!c#-uTQ|C+r6Xhmv^Og z%Xksu4z0)ZqLxRDa4j#=+_TW!?b)piX=$Si=Sr;-e)oMI*Q2iq3>~=YNr6FuJmkag zLxM-PmRo$ads5h0XmO=+)F^XhNU31&%hUN-F^E`FAbv&AVlq*w{Bh*T04oIQHk`(* zCQ@lg@7LhC`D1c=aBK&{?ikNkgfG?D{IH!cN*>riBDMp@^Wh@@>w({KA4Yh z4q=^Ro$0CN-XC?wYLpw~qH8)e=vB@7@?Q4$M8js`m8ZF@p~ULe(J+U(O6$olI3W)^ zk54$xWm#Lq_4lSq^=0jz8dbfktKLW0FGt`r?08vCRDhK?>a3{9`exOu6Nc?W8+TPR zeZRA^bKH*DONZ<7{chz^{kk9U7|eW-*C;EGrt!KAnhyZm45tZoYH7ZI|H)51cj1UY z^(k`Jxix;Q;N|Aw%KcIk+_1qpgttNX(ZR!@J1lIMIh0F=3rBLpCi|gpZ&WL*oS*J0 zv*4ihD5UA>DgE-KBMsN0ZLk}@H5^VWDo51NaC$3$ubq+}H{aaYLpcjcA3L{1Ek-QNZ`_b6kG*rhsW6<# zko=q&8mUUL>^LvPgqr&Iq3KTA(TZbR$h<9wlh=Zb8~j%q`|&fph%Qr(m%)sa*3cn$ zKd0&S&Goz(nd9U0*Fv{-9-0CggD-G|#U58s~QJd^%4d zm5BgdI-V<4jyCQ!BclqPvr&cC*%*#!v1YmN`byjN_4NvmJ=Y7|jxJ+mQ&VwE%ikcd zU(OORKs=?I0@6`O+zlTWexnYS%KhfLwPMZepP3l$BH2Mk@L{S)rDQP}hj!eo>%f`L zG~oeDy-pZFB2*$=_v|xef?cs)$~O5z~r`&WH@KfMx|m-4K;tqli;vph57y0e-a8Y*FExSZ1^9uR z7ZnZEqtSdVD)U7a9UXm!JVuWuHZoFPM&ZRfYc(e;D#jT3+V zY_A>Q6H^gW;HN{OHXP>$$>u{DZX<$w0s;bHO{uD?oS)~Xefbg(55Hc|03IO`&Pb^! zc%36kQ(js;Fx+o%Z*_5e3@Qf#S-NBwpP=)L$G-lm8S;Sf$6vG?)T((yXbPuCCu^ZHEV& z-&@EkNaHoury*aBw|XwS&&%a<>`&~BKe>KVXjM2OfRK~2l#;bM&6U+wS64R%4!|cv zSjOkJ%cY+5bk@VVtzPeNmeYctj~})CB&uIF85IK6*HZF)#i|I5`Sb}r1A|q~Tv5@| z>mb4B$@!y}0BC7xY1y;3;pAj3m?X4zyH0$oIrr{BApYcZ`j@&F&4keqcS4>;*# z$d`wGp(&wmqh=L`4H?DCNFQHZ5TQLbGc%irnQvNgi|4asVd*$t>*cPiUN_wW*)+IM z2}#NM>34-{C$|_QW~QdDdp?y_E)%=x#BpqljEsEr^m}8u{+BI zZ=p~>U*Cjyyr7_s)YMe9xNHnUw|1x2ZyaSkn4~701y83ljWQ#oBhHqi=FJDw`NM`* zCR?nYq3igqcdxgDvIj5R%HXI#X@$&tyG6T4qn>@?loYvt&D4zITe(Y-#HnQ3Ua zLnZLZ$px&{ir!NX!V%^VX~g5{LXFfXC(FvpY$1qbmo@_8WMH#b-Q5#k(yp(6ZZV%` z@K|Nd+VVPINwu{l-o3CiOnW1xQn=ngoDmxxo$LR&##`Uh(^F0^N+SE(vJ=Uo-@IPW z5+N?CslKIH!6~e(prPV3fm@};BpFNYb`mZRX7{AJ3{LG)I2vM%jDo`L+}g#%176_e zXYWbQvjo$F(IqZ8ZKYo>HnGq{YKtnJ?{3cT47k}aWu?jNAkavR)70^&zt)bw6@@p> zy(q1e6Qu32?rD3OlYmG-$iOZu%2eQj@R*OE-+j0pB+w%R-{pz z$!6^oWVdI)lFilKos9!?{`p$B$u8Ie^6r5B>3_u;X&cyg6{p#TMJ0nDnOo(`Cn?uxbRC%A4E{-4>)=a-20q z(rm|ESuHa*S;p~H2l-&TS+<&OBjgN3$&ajl6oH&|a>+xxo#fb770B@!8 zxqX@RZqdUEzDdD7pIaCa{_*37;}LPJYMxvMmzA-+-D1Gy7Po=A$rjVxRHu-d-EGM&$iv z%UC=fquJ2hJI2I#biUuFm8o@$5;*G&Q~{z?79YY_L1a(kv~V|4rdj;)iHL%N5C=y~ zP3`uk%^+V#P%1Y*ALbSMTn>BZqw~x@z>QK~SSEc*@9yq?_9XCpPdEo3=C!%gmD9y; z(z`#~V&OR-g`@NHqlk*Lv6=d$F7lH8j?w=<@Y-X^tG6Qr;|qGEk9XsAiT1(fW~;>| z<;^5FY$Ra6LJ}VzpNLtf+H62$m-%0?a3Tj#&DQ5fEsw&lP_KmVXR_PfsdT!XeA_#& zX)8S887*gH1zTAlQ~X9i3=@V)TjVKq#+7I_(9+X478UhZWQN5KB4&=)0FaeQ2K~!( zI0(7SJH67@)<*hm>04h!MMWVf>$#bkhlJRfnGfz!4;2*@?vMY(2KnxB($k0bt|cZW zjrs+$7&P-(t#*OJ{zG^m-~ILVlSD%GB1d&wTdtNW+BhB#j>@X4z18kWw9F~6)lRke zTv7@;f9rq$4izH_H9t2$9l0UUBGKz-L1LZAfF_!4)#Q79vMH~-tpZktZ<96}v3nRHxyeEH}~#g}MVxw#un4sF@G z0`lLv*x&F*I6X_}v>4WxO=i+gX&a zQdCGn-(oFNDa^^rT5a)Iu5);jmXh-N^hChr<_x&NGeNi*wlF{e}j=*qaIXzv_ZsF6}k;bC%byJ=d0zlIov9 zj;75P(AuasWN9OS!=QMK6;QkV_6Y0kPI)hYmdGkD&d%1ih;MI{PuHEhtF2VMy}jLS zmz|FOewyD0#m62z;ABP_F?}%1?^SYnMI9^=oBn5Rtb}E+h4n>|yFApOJTgYn^o;)j z%BQw^U2pQT&p9!}T7K{#+_+Ia7RA?&qc%068I<1Enilz!)=q9Nl4z+z^o>@8p+>C_ z9%vNT^s;a=vq=pbuhdMcYeK(AJrzq~jPKqRLK5|SFUcZUj_@9Es4ez z)E22sPrku9YFO~kGXDlleeZe25ZTSaCunzGlxSR0&|Grcc}|vcjibXBU;r>NYaDh~ z)^dJ$eR`^iR`A32f(d0?NK;YK4PZhXl$CMcHMWE7!`W{+bbGBg`uxZdzP-QDZ1y&> zwD+SYyaoH@6vIovz!mcpAv0|I^R!8^lSB7N%&kQq;~o7JYRE*rj#fibjs9XlvKS+D z(NW)3fvL)DW~J1hg2(aiaWBmAYvaT{)WF_GT)*1~5k2qy*pQfh;7+YeT<5RCtm)xQMYBIQZ+N@bufC znwrTM8_5Ru0HM!3lnHZX8%g7p4UmkW4nJ{zCxR2z6&NTAjs9VC!&a+JhZjqkU|*qi z5r7QxQ%txM-baGaVHj{1ZBQ;ND~t8~d0A1(%{^j|0v0W?)(Q{!v+MdS;+dL7nR4Nq z!$bS-58Y?@9HIr8twz&jf=`?5JMLIYi)DQ-2DKqjd|X@+20q2oGSgts8~w;Nh$`2M zp^QbJo!NnY8Ge2~(g=W_j8)fE&XNl$z90EbozQ2zX57?to|-xx$Qw%Q!$d zz#1bVA)(2q5&Ka1<8s={Oq|KV0R>|sUN36%JPq1vS40A9>(y94Veyjxp0HVNu28EG zw!qadu#6v6kz$7GH(ktJE@hQ5;6?Df;qANr7ii4YmVko;{Mzs6*Jl_4!{&M6H$D^O z{i8^@o+uJzwMHZwT3V*dndQr}+nHivFLucQ7!?#4xGf$nQDryp-uSV)x|$0Dapoc4 z}a68Djd%P;7sSe!+yQfg%|l{ zcV8d@Ik{Z?Ywj%$zYmNojO^d#TK)acn1c2^xJmP8Qen(|PDe6xte9etT4)ZFyNwqc z&oK~VO;^LOiZx4}Dq-22EQYO>0m#oHWvA_5zS_66X6tvRvAL=ge)FFqc^XeQX_m{8 zTK6lnjTr^yHW3TiaRcRefwj2k9Z_7YwJ@L5J2|vCG}KaDJZ{=}?=!ODd_8TSNuq~X zIyE98N=_jlp(}sQ>T;{SdVD1!a#A)toK&oN?yYZQQ`Hm}Hc@lwBC5xtN&VO3(zUL( zdb_DHP)w8!6C?gD6aDyP9)0m-zp+bKR{PWQg$5G~1OErHBOtFo+}>WOHOXH~(fIt} zfy>q~pc{9#w{x;&r6ZozEw_fp*^$uFz7%Jn4OViJme#*JkHx$o!Hj|({rK^by!TpQ z2{2quUgHustZaX%Xx8_}^Tmo!$@T{iIRT1$jKMsiiF>f70Rlryt0G-7_c0Z3OhgIQ zUVxux@sA%Uy~n7?i#qNlPrvJvrp_=z0>{wgNEOk}I#d&#i{$tDq_4Qh`M94chYx7C0=3)Km#jj67V*IG6sB0uWTc-d^ zut9FEtp%-lwozRa6%{qiO^{GfocHBZ313`ggN&_~O3R}Fb$qTavO*!hY8Fj`b}h)J zb7u3?FBER>y5V7k8XY^B0!~*91wSZ#aYaSi+X1HoT(1C{`|1@1MY>Ai#K;I04FMjW zD1|yg0F4H)t4NJhofjfnn&sMdZE=}2G<4FQea$z6`{bo%kzR|A_Ru$U5mKu+M76cG zq|x*ev?4g}$X!D{y^^M;rdeZYdHI^HNGsTjef#t34B~ih1mD7`1nAR ztBuyh4HXp?1JC0SMWJiY`3qJ+u5Z<9*Uc*C@*E=MX%c0C(%=||Y_2ieOImF5Xgys< zdU{__eR;9)RpId?*ofiJkL_g0OZX5}c)7-B3+NX1$sREhw3pf2e}~BX`#a=+_4NGrrQYf}aJ7^kIw;Og=vc;v9eF#DNL{IVd|;=hr_UxPEiiwv?2VXc}B^g<=bH zoSn&~aXFoByL#hE$H$o9s!dPml-B1IwNyxt=7>jHQdEkH@)ko5~bxP`$#y$bVmXWl`@3SO`(AzIB)-2Q0 zZn4Iq2*1AEbKq$;a$6u~z!)oEUw`AiX%PwWd}a0{CM7a*;E2VejRH|8es^*bU&F;c zE?i?A;X2hE0_ZQxA-@19n-^npr%_IMuRV3<1~8SFHA*KB@=Ku)S%KPNm-2OrU)>W7G>Rzg&3006At+L=9HDmM`O_^#L@Nb z_M=n6h)d9R()H<#DtL(!W=%OD?;xNU_44jBHCQSw9rA7|D=x0@o0>cyZ@s&iCk_pMjTXoQOKotO&KMqMX?@S;acJ8hkdo>auBX5F_~GYnV=Ei7 zpKaJ7UvSYvI{y5@K?no(@jT+^$o}n9{whQaplV$AN`<)oM;pZRLU(6XF)=X(zr(vDiQ7&O1HcCfAL>}MAiC6l z*O)X^oblH5J!E9iBPWq{jpyErHsvk;>%Va!k?+h0QxJfdA6FFiIxR&4Fo?3JojlaY zmNRw$C=VpEt-fY>=&=y@9{YDbcrkR|;7Fu^lT*<~Bf76F8yOyDYP(*4y!O<}oli}{ z{&XlYDXC|}S#Uwn{A{r%XPqvs`{evICg#xYcyw+~Ge17cS8sFsR~GvL$Du2kDQ_2>UCezvJ-Ob!%i#4nygG)R zH{Q2(L+XuS;S<#p*xbJL`-i#r_xGiC-vds zI%L``($~CG(7&NYX+E6B9<{XvqI%-Dq?7C0KYx@qt6K~9o=yH8?z6)|yMmBqlC8eE zmzT8?5i#=jZ`ES@E?|b9D5@{|fp&DgFM$MMOm*WLdYWrYLagos82s{ zAQ=HwTDRhKQOHx*J~7aTN+DL7KG=R zEc^O^{CRtIYYbjR^sm?%4{e;Q%J*M7>kI8f4Io*{8lhA|-!^@k(~D zf)p920&Sv(MgiGPjNeBHH2P7q?aux-1-=Y!URnUcxI)}}^=fpSA%?#-=mT1xm}nt4 zjd6rHQ{1+jw^%Fortdc|&7b@U zax_Y1-Va#+NhRb!^$-Z}T+QcCln}RV67Cuokt1#OKzqU3b{h+OjszuEz9OvExZByh z)v(u+L#s5&Uw0pYdgVg?GBDw)?mxm;H_J>0Hg_f(P6W=6_<9szX6e z?h6;Zd@V{KCYaL67G(!X9nvUH9NEH}(2i=%!+qR-2zMIpT)WW=j{fBowd~yUwX#J%`HI1??pdnZJ?_95Oz>;(ndVO`+ZZau14u&Q<8w#Gj?hjx_2f#C? zk~A+_WSdBu?n3`h?muWYzbc!8h5&~|!2UL8*nQ}7`LI+a znZFjSFcIB&0m%16P(k~#Z`}hLEC#jC!+{?}iHSY9JsgAsg1<&aqII$r!Qb1+Mj8}j z#71#J2cx5-(P$$3Y+s@kP9!!g*sP!Y@6y`!4X~dJ=HfeBaB%y={1+j5NH^|a}a03b1AE_lR!%(NZxKbN6Y*j z9{%go((!cRImaQHwT%s0;L-VcI$zDm3w-=li$zGn{T5IjhBhq=V`m&xSQ=|kr?O;= z>gTA44x(4LexGny=&u!+Xf&#}^Lm}0DwnK$O~Hx%EN0C$c6uy69$?50vz3#U9HGG% zkmDw89o>1I@49q&5&bKEc>+A)-5oa8H@>EgnXT=XT<&gG9`?(l7wUvZ zD1T*3dy#g)Cj?Wh!J$K2bw1p{o({O`ycGUOlBdGB<1spcyyVwx%TakY8D9oU+}o>> z^5!!cW#tMjT8%gA|Kqo1<;C#rZAUjZEDQ`2xkmUs;;;p7AOthiRW;#A6&33w3F8u= z?HC%WDK0LqsCYo5rmY=;^Cc>(dSoqJN2i`Kt%3`oa<|9ZFvP8FZCz9hwK4l(*7oR_ zfPf%Hj$Xa~i@$aM2&<)~Eg-H;IkW-Dp4sa-dMIWhA|gVcu+u9Rc92X@)bIz1oPVYs z+JL6t-!F5}tBLnTk0))#_p!MrL&wO-^5jrWVTIGkp`dHBSfN@+l?{QCy88I+=*r3t zF4??=r*mjeUf$*=QH40UTj_&EcxaJcM#iBU`FI8Z%-a-yn{f1$AdiB8Pt`9MKKT3@ z0v)=q8XyVft)+`cMXi`+DuUG~%qyv?is6W-i0%DMN!ivk@Jh7~+1;*V$(`UPU07HI z9IGgjQaU&O2yJr&-4Ady|Gln0z2O1cQNK1gV%p$N(?l#gEG%D?J=k2Y^ZuI0?ZnhX zRn^h)2&m~&#&JZ^o;-Q-9FIDiSNrSc5Db2>rmC-haKH?O`04oS>6w{r1l*r0v{CUo z{ZC#ScPOwM{$~AzpLn@FE%d7zV}s4C{y_4we9JQz18u9F$vktQO}x4iqEgN3>h3tK^;z`|FFcvCa4)ZZW0;miCb*r7&WaB^o&tqaQ6oOz@R ztri6Z8Dj1xTn^rL#Q6I9JrP|AF&wtPF@1FB@o~BCvB={-LNprSopfkWpgYLoV>BjN znj2dvou&zP^)4Nd4raK`M+O9} zL@-eLtY@|J#hh z*8={xDL^Ll(@~@?*1GM@?vrvDjH+cwrO>qd%LXMSrEA8oPrs&@J?|zp4Rdu+^# zajdQEM9|DKMr`e^q9bErJXUz=4|CPc;LW5KjNw`k#N4C}VwAI=a7qfAJyQxK*DZ zWn_yrMOcxR$Z)ttuEo98mA$y7PB&t_$)WS z_dO1TvV5d!<48f=0m1ZKlj+dz$*-+bD$loYFjh6{fEu%SvtE(;~fjg%G%DxmY2P@4rtu&Tq^%1 z0oD#XmAOc^1KR`u-=l;%u#u3X9%Q8s(qr}p`$12z;9J?nvP~W%20(lLapjgD zzVFi4?Q}cL4{yGUnNNRaz_0z)*x2~{_c9^m0!Fb$nSt+Ce69zx&&Ec;OaSX@Xc}+# z@U87=gxKU{?%n2|Llpfu&}$?w)O7jBgX-pLB}`0Abi(@lL6f2)Ul4V;;V?4L=n7<2 zB>L12P`CM%s8RiN{d|P~o5V`vjW6j5$|;wz;71Y-FU2c;?T9YC}?uq zb>Th)LdYNHpDL0Ta!qzIqaQ78Yz}t!&%X81nyl9AmA$8yQjo{i2sX9Qw=F0?zc`MJ zing&XX!5R!un40=yODnv84@c)HL&6AQpHNTKX<1i*Mri~(YaXFSTr^=Vz|2d-GjH+ zmP0vx%cY7%L;XUCx5e-Si7A_9pI zlGi}yb9FV?Xtz1mlr#wC?(OZBET2C06!5l^m)D$SayK;%ZffdHVb2D5bfxk2;#zMk zenY)wO(Rg#B^OWrSMU-NEPqKW9~%6K0LVKzv;}a8uKXp=4|Ca97@#Q;k4}$| zNd@^9jVsawLBGNzP|1Ay^=o^3do+98#MnfvQ`BMsV$%Pu57Oa%^ec99@-7Olz?@lA zlgM{M07U#VGg=LLlmrCdzJKTQSkiM#)hRZUumuuty~Tz21Uv@$j2yIQ5nsOO)LXVk zk#b7K-vW)bv$J!7txO^Z3yVUj#+E)AV^dif3p=lL=2tLU=kpFB-#-*jQu2F8$;8Rz znDj<}KvVYVPg{A>^T0?!qM)>tnU+JeP%TDA`Z*e=994R&@dkRKnl(h%7DDze*`Pc& zDjYC|RQ&F?;^M)K0=_E;7^%LhP+esFkrxNWH@tsp~{o{<($o~0B;$?3h( zp9mU4-qqAJxgT=zV)A^Tk=cQz%7& z{<#ShSMYx(wG9j~47-4Pr5YU}HR#mh}z-q={w8f-e> z^(Y0r2e&7SHTnoo;>X6Ap>;};xx*h^U0p?uAJ$wv!)GYbt5IPhf({V{wZBidw6>C# zj_B)?&gPUD*f?4Lwhn}0K$Qu!C5H`Z+DB!n-D&3MiA&md%H~Hn01Azxxo)Sem=gjvGLnG z-&ZO-D^vj`)i#@dH#SHq2nmU)%7GE1Beb2T;{k=T%Tbe`Z{hFn@8xw(jZkn}nEPBL zkWByvIA?twC&X9Hx(Ga>(Q0rL+`zn6%T@#0XPRYG{1Q3|VSM+FnwpwcK!BFkcr@z+ z`E$uq4Sp}${hFGZSFafQ2~U8Apa{L(phkwyd33j$DeVJXOh|s@$q>dHaDDZj%=KI3Ey8OtW7(}(7&*IId*px^B1gt(xXD1Dx-1R&DIg~jplaRI@W+uJ)+4${QmU)dp@BO|fO zHE$$>*v-_wK$~>+_4WPq1>K&>%gBJ1fQK~$K;>yzX<8B1gh;L0QZPX5W|^$yPpz)4 zaZaeLtbYI?Gi`7^xjoSG=;<-JmC6Ed@a#*sw=Zkp<&})Z(n?%!Z(mtiF*3>o3GW(1 z6pYWUAMmbex7Ut9C-#vmH7ko2=&}+y;_piAHPe zYSv+boa%{*KROQwK6&l5$6Qi}&@j$Ha;!vk@W_$pHh6(Px^qwpV zC%(S1zq#e@>C^+du@O22T91<+#DPzX8*81ixe z!dmq9ZS`E)r(Yj;l^@cqli^U~N$*-0^OD;u*7+AiiUPUiHR9@qh;Ut-`O$O1r~ifj zx&}vfcl1U~%J$0t0?mK3>C$=4J3G5lI%&wnK@z`|1Z?r+XESvx?w@|EV5ChB~HHc9G<8tdxH8X3SuUfDjTadmnYKfupr*XsX3 zkEOgiXJ%|!7LRBc9YeK(cVDLFJNxfsp!om&65Gq$TSHCFAGAD8z|9(TC`brMh+gcj zt#uk#aP~ySL`2X?pZt!?26b-w-Ts8Cwu(xY7SqMW1(1eWSz3M+ug4JupbF4$0?-fu zr=7>UyWgXskT>hj*x1;79cC3eBN@B{YsbERevcnMfDRq*@87P3Jt{4=1Jmh3_U-G} zOsdJKR|r`;JRun9?ZAB6nb>>_3Q*6@ecs?dVgWwC`mi7`yop#_U5*ype7$~E2(V>G zN0G6)eqhYiY9f86)kQJA{EXk&Pd8}t@)T15r}vYBzkz|ge00F4082|L&w3g9gvp61 z`^C!hTh=>)?dNB7ddkWxo0~6Qyuc$O+TGfk|1;xxGm+}Q+@L?)QZj0}j_y@2ldJOP z6`pj6PK(*;6rd;q1Q(Ar#!NYmuW#$?c_PG}cPFfRm+IT}gClndHrLkPYW_}?$%Vlj z)XgTt_PD!xyPeAx>l5fwQ@uXVl>@-lx=luQKaKdr%~<7EfvRz$^!OE6V&u7nob7%AftcJCb? zKF34{WVN-G{cNpWnBM_tERjG{eNB*=NdwBX<;9krQ+e}*Hv)Rvi+0Yan468X5v( zN*_9DA|fL25Tok#1qGgWH`v)(Ss!R|TT}rwu+RWFwcvIUk<83Y^pFMfm$eS_=4>RL z9Ua@f=0(BtXtb|+q%xI)LqnZ;(!@{$nBFium8fDWP;z})BaEW!8$3;gK;?01H5q}0 z$A*SVYs>6UH<|MlGIp!-YzhX@hK&&jL`ZOOftpN%UW}2azd<_#%-0xs&=yre3aT*O zTHBSMvlUJiadEhyz?0X6w%!`g15M_Rt%AK6*bEFZfSI%`ErFRnwFM|DUf$oKwq32t z-kg*DSKObUn*)%JN-ib_#=95Msau>o@5Y`+I0CUL02u!M_zTjJ{e9aTydp4iqGE}R zxqvyfn%|Mt7xh^*gTsmg0|UJ=1rY%} zKMw}%V%j3AL0_98mGB3ta23+cot;b;*8C-UzSGmua&))u>(f+G;^beysB<~w3f1~e zE0Z>p^qbt%1zp_bdPop^r|%KYoq@q?p8W-;pmz-vYl$+X?(&}X)~h)YBJCnu6vM41 z!2|yV`zIwNRvWfR%Du+K#LS6F$xpWMkwjcB`ysD;0TueMq;0!k!yKKq z*e%PhshRAZXP^@oxw~+hNsEt<2O>68--q#=TX3ouFH{UQ>yW=bi}Xj$ngYxn!u^gE zQxFnpX>F?%Dj7w}%}(P*kPH}>-K|6W7X6#xf^98%U9!j!Lpxg#%m&R>^+d-C&e$Ik z8>xqQ7escjG4Z|wJbWa29q91;@o}^wVvq|}@6gd3>(g=vu`c((M*Hk+gQCzmm&+V% z7)xR_tC8yY_s@5+50-2Gy^CPj6EuDUq2iLyrQepM7V6(RPKW#ECZKOQ`#s96TRWHk zR=uAg!!vDQqxE#S>D9Cjbs!X@^XFNV6I$k=%QS!TEscOcOOHZ|>+V(D@bEp<>0;unypYaQNSDL<>sNEl2%aRqr^~=FJkbU< z(&Zd=!1nVI(ZBQG`+{IIB+uw7u`ecc54fS`yG+XUTK+%ycOj%Nnc!^!v z{*mXb(<5LX@~@A5Cy6o)<4=4%-m=f7Fwmb7qd(zGzyI4Vw&A|~5W&egbA(Z@B~#g@f65Cp5fDncV`U` zmzB5OgW|Q-Z1YO>-(?$!+WyQTlBYk{K!3ZEiiV%dzw%nB;#1oT5-Z9mwc3qLG#WsDZvO9k4Nz{o z-~T_~RlznU0KV}*8_6tn$N&8r0~85JxZ}TP{qOBl92TwKe|At%KAQfY@4`U&|Lj+3 zf=x>@By+Vdzm(U1Bmy0g0JH?6R);&|fvOR~&NLK>AOBt$ut%&5QqffWdmg1<_Ov`H zZ4#h8PZIPvWh4CvNN|3qxfgry9n_JK?WZ`ut$$K3aA!YRGFt`O#wq}KAauPS^@kB6 z%1s6a$dOXK-X9xXVauf~b)>;uh`KNFFMW?1W@f~#4r3>#$g7@|+iCh=C2zZ)fPd4U zmhlNo2SfAGi>Q)Jg}1(6*Po4Xi6oNQo33YKR(=&xx(u)T+xh6<$Um(E*J?35Af@~C z&rF|i(P{PCP)BP*l~oqj2X@WnHcY0dW0GzH*arrC&?G|Jn22aOuFn0L1YJ6QBs`p* zQ_l)CT~a4r2*g=6s--hHWpwg?ou3fr@-^gEdnk?91QBEB(0tq|MQ5&npm_51vHi?X z|MAUeX=&*}tCzj~>TmzOQsHb|k&^)h<;EpaFW{Hq*R_o~^D4JJq-fhcxTjx+{}*#_ z85U*twtagk!YC-+(g@N$bO=aFNH@~mAPq`)N)90)-Q6H9E#2MSUC+Y*bKUp7J=g4d4KVvRMm z+-Ka@_dRU_C_jhV&E+4szj8gsw%leBx1PCL8{wh~UQsacw!G3e`%p9GVG6z&-vGIM z|498KMw+m*K+ik2ZqDQj33{4I&Fql(nOMk_lq5ds92QyyDNoBcsDvUS^~rqt$am7a z4+@wBd|>iU%DIQji-@>^q#2}hv%J<=!JKKuKq*)AxCjELY4PHTp+M;YSM;&53Etbo zjGgg$Saft-64ci1s-x<$)U}c97>|A*mBjD?kSJis@`m1@^B<&S4HD$nFAd8@MdF(l zb_RcA;u5??Td3$X{;v;t+|yR00Vpr%%$ag{b9SVn5x9-Nq9TCN!ueVxfQdygXNV%N zIuM+QpU1NW6tYF^J}uAwwg_RQ2{{WxAr&u}T0fSmrtVs8gIvC17XPZ+R=Y>h-oxgM zzIpxCkX$g+(2=)Av4lI5c4QIpafOP_nIU*T~peA|o@N&;) zj+nzI^NPS}^H$5Kwl4FhZ%8$Arm5%hf(uJ(IQ>%L6UbYnifTTYtvI0eEvHe|7WxQ; zz~*dLzy~1I7(}}-`opat=U=Uo5K{a2G*I_382P~h1AyLy8go4KDKcJx# zPJP6KEWPXX-+jxtoA<+VN@|A7^&nTJ4tiH-_p}5EWLz(_BBxk-SIzicM(uSJ;Y78Y3bI~Q}*h}|LcuPc(i4I`iu z5k0g=hdVl6G=P8!U;^puo&e!13m#p2AhV-Gcgnm9glSkc-BWPWzy?4m{XnaUme(CH zORYAue>q~HRa)j){Wy7yapCae1GnB-zH)A>q6YnhITXkQWi~5DnwrxNhmAG`T4V`Kk01%36GzLx+M&>l;Pz3k( z_Uaw?N>dR@SUqkpXAV?^3pMk{l6h=MDWDYO>Jn|9SNpA z`JXJY#TSpg^G8JPV$P9>&&}x(ea3ir^59@LA(tIkGL@*VcJ5w%06ej$w7{bMBQ|`c zrsZ=@lB;u9STY?Q-RLM-3@NCow}Jh=*>>$EZ*Ncx&133`=fgiPbfbAjeewHr(Mz;S z%^mB0IS%gETSi-e!U=rw^xH4PayBTN$H`fBbJC6Pz!gC18%1Il9_6aOc&j5b;P+4(R}F~7A{@XC!( zG0Ee43v&1Ie%EgB=g*&v0ImO*r9MG8@tYB$+aB$fmy(hK--o?}-P;$s3m5#m^OZAA ze9N@4Q|9zEG!GzS#5B*W$SRuPW(V00Pf#c?P&%a@KNkI(BVR#+KF+LE#njZyljjsT zzUF*UY-!t0wIIHNA})%GXLf^pqIVDfcVvGj?e~@)-;<8P`=IT3ua!&SO3s#sO;3&j z2Ua++l@}Fnu}|iHyCqRh`GzHC*Kqzi#q&oik5lQJhJk5HYC()a-WyuMO@NPA@yi3U zndrf7YHn`t?t<_4Aj1zUmcO8Q*a{v2r{yDhc6%g>NkW3n%ut~HK=K}CKw0Q!K`DwH zpo9Y{eD!7%mfJ5`TU>2Ba%`bIZtL22Exv#6RDd7KtayT%xvt7<^z{jga#oh zuKRsow^u_i!QLL5B4$(5Kl6M|V~R0BfBpo@XT@P*llpMHk#<%MT)9M~#Y&0d@+0nk z9V)WECoivP0@Wt+V&#IS^c%vYDCoo0bLq3u^p?@VxwKnf1frNXcD@94m77iaWmOe< zi5dJ+)Y^S=?jLjaWW`x&2wc1aQuDV^)MlJ#_HgW93r`Fj*r$c1pr~vNVZTdnuT@(m z*k_H&r+CSgyBZa zwAt_NW=A@XJK}_4VpNtvtENuzm7UaYQT`_EnP^jw8zUkRo z{S24cIySeS^6t-3k=>G@?@9Zg};X&48EEu(H&FxR(< z){X#rFPVsV?0U+mj4cYzQ`_rgn+Wl=qyZFZqYOn2Lz`^&_{duCMP;>O1QY`7Wh5e^ zR3Lu<6d3TLmDBgBp8zw}2tx3%4-J$tWINrw;+Z40`YxBTf8!;(xs#njhU2} zmF?{8@bZFMI$64IdO5u&vnGC}V`m>OGM`g3sL-pbI!j9zX=NiqAUH8xJ?2$l1b%YP zl7a!_c(|n@@9GyvnB8C_xw7w)QcRqqOUf5GJFQRcg*} zNTiAzXZ6LHSG4HYJdUj`6MA}jYzBkeF-*P=q;KHCX!HIUYOZ;iMNBzhZ-UxBGpZl+}xstMb@Y2`Ve*A1V2?7Sr5q~m4)lt)(j&muWK7EQzcnh{K`2MHfIgn2chpi{nF?qSUQ~;$0 z7(bC!YRzTMX8b1bk41NnPEEz6#ICPzE6K?X&(GI;S1&mG``2^B`tx!N3yX@ffasZ+ z^HMpP+p);{Yd;VSo+Mp}`V}Ru?(B$0>D$SZoykOz@0jK*qJ9dA3suD2?(}mh&%LPX zG$iAip8086#1W>L*PBm6BSo>&H+8aWRJyVB_T)55Q7N{XmCf*D{O-z5{>a%p1;AwJ z!;KhEji=R~d9R`cR^;c)6Qf*SUTRvH>X&m0Vx#)8tWdFHi7W=NMw+vcx0} z<~T=f%IF}$Q@vKfbQm?%JHfpk9_H3L$Veue zV?Yl9Hlj(g`D_30-zwF>%`;VgQoK4bHUTJV3yZ{)4VH`Dc_H>(Cy>$yB+kyT{>$^3 zgUw8F^5q5^XMCvn4>d)=<^uezUM^F?*FO#e+w*RWeY97H|KTf`gg5FnfyG&;j|Kw* z)E0l<`U}~I)sw4m-g9GJx#hgE{0YyJl<9{5VtZ}RcR8tH;8Zj!FEfz9QeTo2G4$mZ zC=+)9V=A9>diC?QG6Ttt{?xd{SQn5kw0(Bw6S!jGW3ghCnhFq7wFyK|&rhUZI9=EK z1ibSA_g__2xj$Ebu^E}6@G@)#7`W9+csS^I_ihr8}@rS2~O()S=v2(X^HSylVZ2e)ySw`{;y z_()h**>3@p6uh0^Hye)KPQUXDeifN&xU`^6;LHL3KX?}bT^u>8p6>qs?*7p5a2aXw z@vT!p`Wmha{O*RyUHs29v2_~O6TBK5{NsgvY%r1St7Ey3@8$2PS_2k1cmEFu9K<+|JQ{7 zC)f*Z@ZP$uy87J^PQc&fJc4x-6dNBOfO74&vT-T`el4TzQ7R>x6N2FgBrWu0p1^_c z=#gTNC|~LCwd~X|^Qi`3tx=He_Xe9NdqR_lX+%p>viE$C8$}T4tb%F4E6#YyE@w1o+4c0y(^Z2?Tbed+R&+YvGxCFt-IPJoKD!TW6_o z$s3sfcOX@UoSaDJ?cv=S{nHmmHaLDm{Ng}&Gj-_LNcEJiPW-v;w4E~wlHbl|(xo|~P09QFrR2X_Lxt?3_v0biImu>%4?fE(gD9DLrG zsgJCRN_=%(L224hTdz>2+%O`D3)nonrg;X3{#g7V(K%nmQ`OMaJOCwy`@P`Yw91bn zWa8)Z4>p`{WUPpyhx98|Xt5-l=g{_^!*{FFHdNJZo61KIeTK+?C{t-fKrjNKg22L) zlP6ow@kaa6#|yx)cW7fuirbI50(`)oK!1csVu|{BoIc9zJ%?aUC-oMo(?8~g5O#U( zPX#4)a&u1{;IK*B+ssGbX_|)wELD}E*mUB^>cz-@!$sFkW`c*#XgrSvH-VJnO=wYvI;^o1qiq6! zajjI=o~g8pyF=G=u1zEs!~T>yu8$XLI8(J}pPdHi$<9uY2}p*)fiKe#2q2oxLoC7H z#;p4{_Xxl|1mq|jlmHaqTiK^O>8ZE%_1OFXQB+g{deA3YRM8J2LxEu+d`W8InA8Wz zcfi>YENMl{P0aWU2w!WaCs!wpI=SFYvO3}Uv~h4Sga}?Dr1AsM3tX;fY+`a5ROhQu9ac@@qfrY>MM`7U{aLw-z;Rie3 zLpJTFlfNVjpbDCpUu=Dm6dCvzIF} zt7~_8lw&Ps>Cu!!3ASkX*ee?c%F5agWAnv(*p+}j4HXf}MiOt{$uy1i_rHlR)w^E( z;&swdtZlh($zjnTj;NpQFjmp#zdFfz^*H|mi2yh zf;RQGe80wvXIz@V12p!nq9zB}-D4!g4P<@uedt@0W@iV&2L42#Y`+xpZDh4bWUe1K z1zU?>C1-Y4?)gK;)7Il>^WSm&z-{;fe`shZ`%^V9Rxq1spNgYnczUawcgwG&-LG9M z2+zCgxwzGfw8nNE09m$ANGLZkk3dZyM}u+*aA0+HwNp*a77`NhO5K=P(Ockd9y2v4 z<1VUvrnv| zl4|L;4?90ULZ<*V`Fkr**Uvz8s_GFD&bxPSIt~IV4s!s6y@j}zk!lGWAPhef*2;;x3Zhj0` z2KI9TzSFKtk5^!o{ChY6gOe{@TdT;h;tR=(yz23YPdj6#m0{Qq;96m!kk^EQNYg1S z9fPQGz3zu;2wrQp`Ta`j>IY8n$u=X7+v5$#w-N&wy(B|B4#1W|FBsSUbAHHHG&{S# zP68Yb_f|sO_&i&@o?G26G_zaXyG`sT*I(?uj9s|IxxT(C)~r_}x82&>D$3p3qyD}4 zk*y#{mgOa;13z($#NF*Js$k|@15Hgeu6Rs5Jk!eQpqDT6sq=YwcomkGAZcHJ34D|N zp~Qmys1P9yLISKoenVwtMf+QdP#Eh6R6MBV^7nw8`1SnI#PQgHfq}W1YLAD0ts4q8 zEv>TWj`WIoq~LV;9pk)d3oog!OLTjCdUWzLGp=}4K~cftk#kEBifNw8|2yBg7>V&& z$tNOgRj!5Xsg7wdzTa<~1}@zE>>=uO{#zpo8~oO{@d@7M5E4GiHC-rrOBInqieTlr ztFo99$G|9L*hjI+2 zI(UCM^WG%kfRB}?yUi9{NM{ab1Ox=kLH5`SMU^;z# zY+~!oTT{_b-)YA1;BYAwU|M&H(|8}mem7j5+@BRIvs+D7?59+QOz!uu^@-b;C4C0; zU_484OOkNm#8EPwW;ssaz$IIU40TKmL^F(#*ASWj;&vhuV|)6Rd=_-G-^?v5r{LRW zsk~N{-ZyY}bTl_F5F_uj;i0CktIy_UIdPHM{=cS20g<#*{{8;)=IV>Xmt;=6@sYNb z`J4S12?RG$ZWL2b+)s=_B6jZ2wzqeRv>LZTR5u!$*NT(uX8}pO6R@T3>FKT2uvE~8 z6BNsoiwdB9*Koz(1MYzP#3c8!>t_jcv1I)F#kqNqSMpMcT)ZH04JI`eM?Y!aSIvv# z*YTEoP|KQIaI=f3skh0grTe1fI6~G(wmwUWHZtHXTBEepCKFJhYTvvTgcz-G_&L}c zqX?cku+c&#F;U+}1(@YigS0}tP#nM78YCxmiq?Ke+LxI#?t2QDBzB8k3*EUU2CCp= z`Ok*lFvI0F-ixXP{Ud7{OtNyyFDmP@I!lVuwi8GTY-Y77O)uGna{KZ||o^Cx`_jk`Y!gwv&Z zM!;;Ops) ^`0e&^8{MC&rr8N<6tv-9iX|CQRdG~dqH(|<-2{&mWn0-_7jIl@lpo9wy;h%Rr~6vyV@MV z^|Nb?4m=4gd^rpMgdo9_2}10gkbxc330>$(+YHoiw_q29nAmJ-_G)=t5%Ck;cbirM zt;QXoD}8S4;VhIx-L`^gaN<#3u!%XC8iOB6R~lz-VuzT0XEBwBi~9u#+^;$+4_)x6 z5AR)>Ycd{U)WvP?kmjuGDCS{b{aE@Y51a%+)@edDEtH;uj*gA--H)`=!243LsnV#j z&lULfuwU;EV))#FRKn-vc?Z5Z2k$1e4B!`j*wHTbtXRs}O-e$ky#;s*v)wGDvU&G@ zUd`F*G%y?+3j^ZwRIx?^lW>21ACw}+QG`KCUs@MR7LpKz3gfZV=)hU-OAKxWMjkTa zR$mZM^pP@*V5;tD1^8sjR4h84KToVuGNkY!P1lPS$y8ES+n0Ec@??LE>MBM*fl!b2qvs1ACv({9&7Tb`(J?SUO9l@f`^hFFf0fY< z*JSqKd>Foi8yMqF3m120#rOG-XV^CRG)NWyQ@HmU1C6&!*T|li_XtRByWt?8DJ0hN zJRC(~C`#h(5-Rl#kAhxk8Z^m916xpx@J+j6InJFDPB;@S7Gm3dyxcWSxPXOJXt(}L zWnY#crm&TwXO4%rV5u;5+T7ZbM$Qt-kPIfvL!*k(2|4}j9HBxxTw#_J$UFDvu&O`h z&W47LYO2EI1Z3fcQs{{pTOn>Pc>TR4Af*t!DZw3)FU>_j(_w)qPLc60y9N4sE9ye8nkG>%RoT+-Q?xViOa= zfpN*YjNV`<`u6r#b4~+>hrh@F9_)CWq*-xCKw(f#4P@r)?!-y;)2(!d_x}F<*$@w- zvNlBykL9OGR1n|4y_2T|m`U~9yE|YGpPQQndc^oR zK0EKDp(e>@MSW7;|1XBKGj0-$c!S%aL>t>qNnXjS&1<(DKgFz4;oH(Rp-haSb-A{i zB?JBAiE!>Ni6R`K@eL(PLQ~wUM70n?l9xg1w^T^iKj%UK!j>nd3$W&&FnqHSK4!$9 zyABj2-t9_>0JA#(Fh%9ehg>nVDKU+&s+!g;Y}88Mrh5GjZEmkWSH;#9u8_<)d00GA zS2n_AS50Ker~I2o(0~R zm_r0bV*2K7BIT^SgebqMw%qP^DF0M#gTPV=n@>7GVkY>(NS-r@=LS=#790il>V4Um|rls8dV+B~&xy&%R;m(M2(0dsbr^AM-mIJyVY6(!GMNVf+8|6W z?V)?)1iLSlGExkjpmVeLA6;{Fg+RUrC&%>iC61;qd)sIDq#mn33ouXi@0)vP-8K0BbRcg0O! zUf=FnIe7&yWF)E#EL=NQ4flW&nZ|yRs}MvoIy{Z;paXfs4+C|K-6#rX|#$IVPlSA#x_ zzoRskz<{Gx9tHX~6e)2NM9_tMo|q*pguVvU}!59o=m> zn9vXW@OylhV#&nY>NG-Z4Hg-J!pm`59$S0W3m+xw__%6dFnm}?TB6;(NYZ1$FZ#B@ ztJAOZ*VnJ$P2X>{*tqRCOcCyT?{RnNLv=VPc5j$onl_GP$z;##%jP6z4pltZo@3wi zox|s04`4TYz*L7oO8T6AB`44$=;%T@`v;1rsJeDS^m>S#)^IhNZK^$H-c4n&4|eNv zj&iyFCmaYJ9~~QeW_;XG`{G5b2nxA>8>Y4y-N3(8soNK_>*~BuQ=le@No-v? z0e;I(UvL*cX&yd9okakfW4(!4T9q|aEvn0X2$UJ7v+Czv>VhLY=SD;&-p ztA&(Sr@F7&Fp{JlXH_h1vZsw4PH(Qvl^{;oCd%8A7PoMyNBIX zwWxAiS4SUCc_j>g>n%E@ULpVp5udBRU>umfsdm6P*jDlIM(F)xZda>&R24z%1Dt9! zoCNa)Df;tcDq1^E9?2nN@&-0%`nc4EML-P~{4H3PQ+l4e_VYMVr6crUU@9+@tO9P1x_*egor&NUCYlgs-K63NcFrHf1J>u)B9 z^dKZMGU1;xM4lrcfI@U9WjiIsTRG1rk0ubFr)2h!tPc87WMrg+1_!`*QOd*wEN#rx zY#%hUK)~Zq?%lZ0Q8%+R94M8YC7d<7T;ec|aruvDbgmt0Y{O zEC$uG$+o#W(8`HYCP^65pUlqA$QZ$Z@*N`%%FccPivk4K$VfEtZy+0-S`MZ^XEE&i zT&e;>{a@X^Xs&`v2@1M_koBBV1<*>SwfzN1#|J2>IaIxPVulEpQWA_AW7fCXw`Ow^WF{0k($^yOiqvT1D(Bq0d`H0R@xf$_%;Zrp)N=$*%xh$3M< zX69w|Wz3fy?c(SMO|A)jy*r>453pnX^c*!;ngQLFfV>=VcnDZZkaB9nkrWj4k`g(K zWd`~u9n_@+K7R(u(wjqDOr@nD2%5zb#svC>;Op=@Ep}~hd-xR-8h>InGW}1r6{x-r zT$&%v%@q{LH7zCzHStk47e*|I#fOi~r=t-N{K3Q57ak5iES1p%=r170CT$#+^qs@x znEZp7n1TX^V)?)5s0$fK7?@|Jv6_KM4Co_Q=U%U;&x*Agr$y!(!}of6^BlyweY&*Q}qgC@$POC5)v)u;>91tQtI`9C_{#beGIucK0m&= z*f_2Mm5UHn5cTjsU_B6Ao50dx8^P79!k3wyP02`1%*-6swX(LZ#dmaa7LH%_-~3_) zs3mQ0sQhn!kxh2Up}-q38^9AmojEKrnFBVTyh?XUZSCzoqu^1&3WmmM{1CXcqG(p% zW@f5Gt00-;#q1$5=nZZR`+10b~eqZG+Ir`VRK5wPOj%Ai8xAm%&nNC6)M~ejVk!u`sgc zy3&t<4TfksSB9$W&fZz#sB1|1}Lcqa<@rE5YH4mm8BtBdh2#oGi8WCP1MMHgs8p%Mf3B~Xbs2MAxw4~ z#`JCqE<;(2#73NpId9<~*U3NMI(1+nW0B_evqTo~l!N``9})j4syljpYj8o}{G{D9 zJ3hU=v4c&BS|mpW1T)i}?JCQ=<-RQz1wY_r0foMj5=LJ^R6M*Ooyo90Zjj6w6@^Yi zlMnA{{w2g(Q9+@mwiZP7`1tx>UtK|2p(%V0ox8HS1P7M>TnAU$1F4r+!U_rs<{v9G z=qbgHNnX{ZW^q zy7fT<0a_qAEv-T>QpQ_y@{ftkwP{Uhz?_j12jIUDlq}hIfC9K94u+BVGf{m7)%`m zS%S7fe5l$$`#ky$t@&CrM*u4VPbxpNbS$Z9LLpsY&>s|E z4e7mgU&J`j&*6qHDeOJ2QP@|#e=;1t*n=>6z#94c_y8aZ*NOrx@QKdd^5%ejXyoA*Wn0~K}YU}I)}=;*HLpxSCd zXTkVW{@AvIi(-u&z|}BpK{FMgtpZ`}-x&}^@XFa4+}5Bo8nBpyWQc^1O7iOUpqb4{ zGozgxyedXVcjD%%xP4X;i-iYbditV;aucw?4^MQ- zprWNK_yM9br?(gQsM03@lh~$6otLGYGX`b^UdJMKw~^v++rH5q#rfql%+$=}9RtivE}nlMERkjP+Cz9Y=X zS7-|WiKE2cL)N>SgZTV2Vh?}hedy`IwC3}433%6V2oN?yR)`TU8zbwFGtnVN;pelu&9w7*8_{T1_WCB8Z-dfow zhlgU4lGQRBCs#I)iha+b`U?0z_rk!7QM%FzV12DRr#qS;@Z1v|xKp{?Xm72cMHwA09E=igZKFK ze;)t8C71raK!94cfu6+)Ca-HW2w7g-(t`jZeW)r3RTu*~et=eE1n~+>)=nCP1G+3m z|Mgc-E_Zag8{EO4si25o%}tq)?_0W8YXKVr1QzrvuxB7WuL}- zBOc|_IPiJXQ2O830W@ImSFNCGtmvUXbA?7(^8p>YI!hd|ejRC?CkSNVm||?Hj#N$e z*UAM9ueAZ26tz|Ae4A7)Qs{6FgtRM)FvLK{b$!OCpxp@X@n!TpAKwRG-#(K?WZSOg zw}@DCpVH_jw(R>%nuCEFS*YqL<5~}Tb0l!SB8KxfCI&SIWWH0#`v^9+u|5+|R*}j& z%z;HBtr3E1ox?Wf%TfL$71FDjw($1Ot_^(yrtC+WWwF{Z-=F1P4s=3dY*qgb7|nh| zy)3R@C{#v{QcKER*6P0TnN#a>1`dVg;*22*HZ$3fJfW#%ob3@eBq9B$)y`qEypk$Q zVJxn~*JY=6KHHpvl~E%t@u!r2BtJhp4xr}gITsH6v|}QT%1EHdNhDK{L09--H+>mD z#@9xC!aRHP%R8L^tU`rUN4mysS`b+gK30km7Ofdqa4O@84!1U4M2< z;tv5BXaT34mh+i*pm=xRizla;S#o!GF`o3Qb>Ck;Gy;F=#89PYV#MCtBkIeQpQfdK&x0~$Xsk%9)a*o*7y_lrW| zAUC%+>CXgX&zSbBH|el7L(Rzh2$p02f>B)dot%3t%QcI~3f?a%1k@sR-+n`UePd^2 zWEle|4wg!W@@@_>7J8&eYH8OelFF7g&7Y4)P&Gto`vuAvUk#^<$lb>NnILsVe5dCt)6v~o7FdHrGIMbE;U{=4NiAnk*Gs~zbOV`#t-FuN;RkOWDwY`q;y>&;ZV4s{(Ogt(q*t}rJ>}DjYyk6u4 zkL!g;WXDK?z4Gj4+c3M@2RbN8@}wpDs46+LQaA?7D`tkvYKca&IY^ETNI+Pf7R;_b51V#8cR>U}9gMsAIQT^s`<& zpt+gqU)X!BDCSExDkcqB6_nM)s_=;UFba3tsq?7%Nm498!bHBR=1k?X=|Y^Bc_l3U zX)J&0a%C!ANaLs0Wv}T}G2Oz`wa}H3R&MV=KP zEf}JvuB^c?rc0Pkk@nIyv_;-9$>FI~5>M!u6VwWytXs~4gmoqx{6g6#cj_=4e4XyN zcZyafH4jA-g_JUqCQR&lsd_M7!^E%z1Hx6?IQKlvc@a^8=cIL6$p|wVa`GA1I?9~P zC#4{TRZA~aD$(j#5c2AK(W$*?70e zMxq&+i?PQb%4m}|TkQ<`99g?^0Z5U0gL_bDu>IGwR-f}WnvmO6Z0j6h`uJ` zbKiy|I|}QNR9He)XSWcB6lysZ%R2E^h_Y4L&N}h)H;?V?(=pKO?Cy$5Nn%6b{`R-L zZ)7KPGargCw|iQXGzF^AeootQUl3*0A7p>6r9lwb5#@}C<>N;MK(#U5+`NL>>Vui0fdT$)lvi?xIB$AM`V&ln zO-~w^4V20~7*q%JK~X3=TRJ1ws#0xi&0uY9t$Gf+v$4{Jt4wL?3SURc^jbmG^(M{x z=7tW_I|)tCFVA<1!SQ@Aj{j0(4>=Mv zx^v$i?dUs^e(hr2mN-yTH*5#0YL?TN2`c1xt2xt@%tbh0Sbr9EnTpW9xdJG2(@GeDDS4+aE=Q z`Qt@)c6J$#@86*m)gO3(XqlU5%trIKHJ3gNRpuZ_GCS_Y<3#-7S2czeChwd}=Uomn zkK0+I>()S^U>YL{i7GB3Jw_c4kPH0oQ@)GI5pUYDh@yU0dRwijhdw$*j??-*=`|=q z02*^*SJT3QEpk_&YCymi&m0ZE6-Dsg+#S1R0*%Kf0*)P_ywbv_WQyWgA6LV=S26#$ zpY=b6@;2OHPEM90)jJDNjm?LmVlK6!fVmpYiOxL4xGcyXZqVBTVrWK3o*%qO<}-v=H+8 zZi@7#&H%liMD?&>R0pNNS4$fDl1tiWx@X1^9effDJuJ_vFy9D2l=Fxr!YJ=YaOxj( zP3&%~(pq94q-Q^G>`nz|)eIam^*k}KM6S!~>B#5J?Qo3~?!f5m010_^W&ITBdT4$+ zh}d&XI>SHnrKI@XEp`WVgvYh~XI7uU2WpU3X*)(Ac6Ck?kG zg=IC6&VsUhT~m?5q&hsdC;3^U+SwUvm3IarEgk5Yg1o5C)Rr)rl?eFB2I8L6nC=#~+*)1x#$jKg)iWvt!4~~>u8j=_qk;Rwrfp z_Yfh(D%PTB-k`_%bFKuB)Q18PX71O0iQC&?g3<2oKRZ2@kdo|DZ8X^R!(~KLce+Ui zMFXG#UU)Va7gVs4GBZQzQ~H+_loS}bo?e`uBH4dPf32YA;*zQ6zWM7ObYbK7Y-YmM z+ZwjCieQOKV%`qpjssoXSh8gZ_+5O611BeIzW(~^b^Fw-LX!+aoI(<+E2}C9d8~;kX?ok{$k=%M=i17D)&!JBc+8b#u@n`ZYM|w^vQyTV zXXyRNm^Na2tsIh6KzlvR^jk-Vw%vwW(OqLsLnf8S<}{ng!Npx)0XX2?OvG(mUF%t9 zvL<%CS8Y9;e?>)+dZ%4H#Y6|1AinGQ=~h-&Cw_{O>$yLOm!SeNekojqCBzRi#ph~t zN~T87o_dp}rzhg!c}!kt>gjn?^N@bb1%2p$Y-2l|EuJ`2dfq2ovxNl9{5S`CLtSkh zwIXUI8(U%(*#7i&xhkk}g?EkZoPjPs3YqbYHc=hsTz1(eth_U|K0UYf`OvgN5v@EGxp z^svVMoN5?Z*l(WT5WLFmhN0%)yClB~B&0=Cj}A~1%+C41*@MwFnFYQA{i#fY=vUQT zYc2BZLjTXH(C1oA-H$Jf^i9nxf7RYP37_ht4=l4LcXHWgXcK02%%y`wU0x&aZziUK z^WI`upoZg{o{;AD*H$vpbY0ydjiv^JkquLaS~bn4tCK;AV9E4!-FDp>w z9`__k1qF$T+u-m4{7KKBBLoXi%*3I>mAZC?p?8H(OibLB9L&^BPk;R?5GnR^#1!~} zTwRdJ#jC2Tf%XR;=co9Fjh%oN*KP!Nlr9;hyyIj4@c1;BEY+AvJ=E%UcXo>9?99Rc z_3pyMoui!c)}+mf>rC3m-rs@NriONt z+0yr5{+r{jKDaqo&wCXnM*HQ&nt_Ij^UJC=xVpfVuIAZ>tJB=*JLrNP1}ZKlF0R9B zcH4sIg@u%q!~6I1S)usA<02AHxOa<9>B;G6co9Z0D(!y0)dgf5s*K?VcenVfH}O*I z`N}Zhz!!_!-C~k8YRax@@WdEP69dv*}84 z*w~mLRG*tAj@QWam7wuKk*0z;&F?`XQyT()n0!Uh5GzEyl zzadK3Rz1Xl&-LTuYs!!tDJ!Snn=K8k(|0d*uzUaBLsza027|HS>aHy7>gpYX{+CxB zSasjQ8|kU=lPSKk{SXuo5)>2$cu7vv58%rLELA~a?p}2TvaQJRNwHh=LH((ExiWLQqU3M2hcx%zk*BYx%^c55=EuCzlczf5tw`js?XoU`j>0-|s9??*1u+Umn`=(- zyYq-Qp;BK_hG%MUNI6vwUL|4Y`-eudDN)T?{0W!@6^cs?Emm{u^z9Ra@_*7@V=F?YICLeQhB|w@ds?PP0X6T{_a!$o<&NxPq14Qd;$e&0y znTm^x>*dSi-Rx}#uC(A_VbV10^r4EOS43b8ZyJl@v>tlA?37a0)}9y|djC*P-29_5 z^Ft8?^`*}|2m)yG0Oe!Lq9TupQ~L{?5O{vi2R_MCy=H-ArJ1?8P)+VxK2HWc{qRaq1k0)s}ErQ7UB3Km2o zu*0!&ZbbE;P1?P_=JJW?*R52wxc~O;)Xvb|J^4h)MO0WMfe!S1Rk{uUNq%6y68m55 zy=7FDTiZ6g6zMKO8tGQLQBpv7$9Wup%5>por+**ZIPo|-ws3}=i7Z>D$guujzYYst`>=&)NfEnv ztfkJpE$DREF{GZz8osXG=TWj8-!S<-7#O6iE%q`>7*lacUQI*cEzRV(azTH;*PWL@ zBi#P4_t#8lBPEP(D4&!;mrQ8?1}8iFaPrpHmg~i?3P}P8KkcbS%)a#*mYM?UP0}aj zyjlPY=v$ zziJ_+GAQV&%caO zb(m6BXcqZG%8OAmYifQpW(n}KMk8TeUtIx0XH^wtMPis>drf;3J*V!~^;m^1=%d5c z@LTcs5%w)}b8|(U3`1?(1;KRHCo-5u6*yeccJnbjarJ?&iTk_u5G!wvE8=qZDw}vs8H%k5pXr zuIPi~Q@%A=Ew^*o$pLWLO}|7#Dxi|ll;)Hk^&_R2t>VvcM}-ki>={13V)#rEa86kr zw(MT!L0L1CYGPG=5RGPLP3eUR$fiJ8fyZ z8T_{r!*CMT;;-s0UpB`-ge{v*huD>&s^PU3R7!cNFMy67wr6o!*Qg)>BDDPhL-?8S zhU6I>+ed6~*^ZLcosImdz1i6t9FSx;^|d|N*{ReY0Vvbk`TobdslCU`__Y@1YP7J< z`Po@&C(ODKF;?3bk^KPVbW<%slJ%%sQr|r|7y%`fJ(%2a0+LFD3lTRoK?W~NYx456 z@}}6zUy7O_M24t0nl7CA`d&{=J>JhF`(Bc zRpEx%{z{RKE$IpP7wrbs+A0njWJbS6He6!mbJ0Ls+*N+jDDt$W9geS9J~Feor6=*b%kO?pYCt-hff z`0xvph|n*6eM6h-oJ>qQd4w;W1c_FvgC9#+p01S0&{t|^0SV`{pdh$L-I7VOaRM1Y zmFn%S84ch@5DaX>EtgsX!kb6RPk_G8JI5=LLK~(1$AspiPFN>s-Jcy-UYb_F z3|xZKru92+uKnoBqN@6Eec8X}o)Ll@$?;cG#@0v15yq6u^qPkukf4-)bu)G8%ALDHt?kz)R0>W8YGO!pO25Kf&B ziXv-J@8fWKN_yMHHO9tDxJy`NyL4L8{0Qp4j;n9irY8rJeec>yLu@{p3`vv}S5=iZ z3DR)cF8afQS}cQVacE>@v)#kp*S%i>1Ok>vO%jCJLY|xFL6=Lu8##EMbuz2=YJpqV zk%IGA2|^DBx06L^^#Xh}mxOWxm3Ajs8JF4`Go-$cbC-+m^%)t0tgIFX3zz&?$5R_H z$TX4P3kuF$o848cv8J8U4TkjUS`)H;V#=z^j$u1)eptV$3)ErEWIkmM-#Yesq#j7S4ZVkzt zKF6)_gyRI(I}NZ?oNwmk^=M*xDF9Q-%a=Kd=H5Cw5}v^mhMyzCXb=D!d1hrL$18FI zpz?7eg$Xa%^xmnCYz01TYi>?!aMLETTcGBljhp;M&CWNBQIGq$1i=ThtgizqDjFxf zx#)UeDuwP>sv`xR(uZwc;lmWzqo#>2FPotu;O;zua7pm-@TQdYw!lNM{F6m5qZ5p{ zEJleXwdTC&$*)76>ib=s#x~2>eOCF!k13{gKxDmn!#U%077I@cr*1%kCn4>pgn~kE z{tg{AC6KT^T?H1)f9xv>shr1klduj2Hddc(O}n5AWvESRp)i8}XAu>C445T+e!svN zRX0@6l-GQzr2;98v1RbgF+^0@3~PP}8AKoRC?P1>VK8kSq1e2Fk;OyIaZ=VqS8A@c z!Wk20fy4s8_A6;=v0B)wAHToF|bJ9iNV- z6UP9p$;RwSo}PI!>DL$C={*B|v(>K9$-(r`-A^EI9HcBf#Jd1UPWNhzROtRHi!DzU zDNv_lO)was5F0&R8m~%xAAV0YTUl61L3?m?ISf7yB#z}R-7W1kd;d=GbU8wb40$Jc zSn|l>4+fi~$l;LltrRH|Az`>ee&q_;)fwIHy@bv}p6PpAwXn|BUvnxJmD_xF@61B_ zH!P0KkgbRcUJIy475D%XsHH{N{)&Q9Qpf&{+J^+;*ZQ5?6Fa;6(UK-ooqkM$;jOJW zV%3#jaFB2k1zefmVw5zVo)VTcSGhuqf%6k=)G~?msZ?<3#7JVWv5|1mv-`k>MWbrI zS>K&~c6OFFbaeM-Q~{PCLOesh3boR)jW*(cj9=u48Btlt;x~2fZT; zvSD&>8B?-qVr^+D;J$j5s6>NKJfDylr|~LBp5G9^%@*C)r__%Op;55Mv=T`x0f-BF zG%g+={|f0rsGeIG9c83+2@D1fnAqNV-K-xK6oEWoSZy$YvyCc&;Vujt05thYPSE7n zP}@<6_pgk{f<=ne&#P(j&edXwZLnxq?CmN(Iz_d3`dOUjb7Xr~H5gPC8Wb1GO1h=+ zr_$~)f31>D;P7<&dE?;D_>`MK9ZwF?lkurvT*CRW17v$;U6>IO(!js5CP~0e{$;F} z-iseoI{CifsmXF!79e=$ye>`wSa&bpQL2Hzb+qZ6ceMyzZOP*aY*?6>Hnzi5gGJ5c6 z5Eg`fwqfaxm&Iz*Wf zWlzuKN4a{BMnQUdj~1M)Hwv*g4#y_vvF+p4NI1B-Ov;hZjZID9f&<1UCb?5Uvu;&< zZtm4pz;w;S?14w)!{P0r+e? zZC&5Y5CpYi*h*goAtE6Sc3HZb? ze*FihH3IKjV1YC}>f*yw2>UDpJX!IoxAVV`MDm|bTWs7H0(2S8n+jG|+J=e_TGEzk zAAFh82!G>5+;!Cl0Vxz-qA&ivN>5p+X}B(j>YJ#ozSws@nMn9aiB;#ed)}hwA=#VX zp2K$g*@r?!o14YpTS^1JFEWKmF3$7%1?H6n!R*!&fUMYD{6mn_RIf;FKFlDP0*<)1 z=Vd@ZQ0zbw(;+e$?@rE7`jYOLgapzn6dbu!+35A0uvOF-!H$7)bz>X$^;GN!kuOm% z>F@`St}Xjb%T@I1@ClyBC&umA8fOn!yUuHc=QdWO~Ah}eV@K_Qp2Lt zuzhsH&$72DP|r8ZXBt0%bT?)F?BD=IGfbew{}Fkm-0`ffjUvDo^~v|S@r8+r7lcA| z)SSgxSt9QQY<`p|(c(ZzjPBb2%VZscTQQ6A`DL(vZDz>Mu$XVwzspM>sx2 zf3H$OyG&uuAmT7sm;^gIIL7$36iYh1BlBg0L9BqtEER>9imnJv9t4uKoMp}cVZULw zdh<=i>;nR4N)@bs3MmOa~23Px?6nb=IGdaS5eUzDryC z0CuPnFVv9J_k2Y>p&u5~C?JqHGXp$ZEW`u*`f^8ygpvl0ys=as=RT`LT%86pEswXY z>vV0;FCZAtN#c{@hhVlGcqbB`yhZU*eF8yv$-qa$EV#IKB4ySKM3j)j^03}aA8;B} zwR+AW;|QE&o%Yj%n;y~ZeLfT1TW zEV5d&@a@|m*f2afI>z1oZAKObHiA#2o~ykt*gi~5O@Oq(h|bE(i<|EuAWyVSn=pop ziCK9QuLZOLz&+%9xUZ3+?x3g`ef;ILWi(ZZ z%F7%rfI9B?KpQx6XHN&*&<=~RbW zugMgi@~r`9-c%Ynk`EfcLt#MT1f^?vKV|>hH}(3#=V162gGn`4ZqbyMKMR8I&QY%k z0W;SGJ`pP@HisO)%Nu)viRnBx$Rz<}mX;1ap@NdVEMvPxiWT`OLl@w+@grM(s&^egUA`xw$zXw$|xY==0hW zf$crrR8bfy-GU}m19#pcV=jKNa_pdH5D|=y_4mnoip*)meT89j2L)jJidz`Oh!LED%ez2 z(jk71nHCqvk@JhTM}NA~Q9{Dg^S#ynHidR>F>{1?OnkhcyOe>My1Mg4XX~S{(3S5J zXyk}dR0ISIz}U>&Km*SFf zObz=L|LyvZ3#OJwW^z(ez5V_D4Bz%$>X&pLRgIlueXCmaP9;cJENm?SvE3ICjRV<2 zMtV+yPk^B3eusv%lyT3Yb|{6XNHw3e+%Ys)Rz^w|a1zYbtO&&PQr7(hRx7yu1iZ1c zs}mH?uH-cBSNJi$rbKh*{GjDx(aTpR=B@EP%S*Q-%9E!BTNKfsmd~@xur%Zl36CzO zU+~7xNYkS$JUV({pD}%k@X7_rO9J;j-T01Ey^GZrw=8wSg+xt*Zty}{baay1D;^$> z34m+R-d=h;VB2#!vHZdLSj#B@o_l?dH7QF}{9zpBTDE?5PNieRAugTo!z=u=)3dN# z*@&<(OA9l%HQ$oT>Pr@dhA6p_9$WsXe{4`7ma=LX$LrVj4lA+#bb)W-+Ckc!)8|*K z_jU3eF1)gesyusYeAH{O&O98IMMW3oaze5)(xiuDT<5lwCDp5K?&;8ks5ljM?G)g} zoRxy8;qq!EYxNTg;VEu@0cf*wGJo+RP^@$0^=n|(gw$L($?1AY8@Bhi-@TU_>SuXH zfC@BAa0EQtY}58rh$5%7l)NRq`V3?>wUoxj7E+_*b=8$)lM{eXb}(0EvsBla?wFJs zLumZ!%4jLGKI=LgUa%Ngm9_3K>|9(R*#i3@&E8SYJAQQCN*doPCk?iy(|aIkVq>N4 z1*``N)X%v!Q#Y(r(dSSbBvwpST}H<9>GI9df{n(43HzWI@P#FA)=z;%88%*?s%4e! z!YHA9_iiYQ<@eU~*2BZJ_1M@S+uNaMTRO~B%f2tgFqzA1tINt>veJ8;#?paDH85D& z>W4PoPx3yxWn78-v>JnK_~8uIx*bpI5cu@=w{J>$vbu%4C6l3l@;4J0FEsAWuiFj2 zS=Pqyc7=R7WS9ae9HIHuEc>1VhgqxpM{G6^`Z!JA_fHe_XicCARkv=dDKs?^DxnrB z(jOzf7d18%ZY4brCcvg^m5t$mX?d%b?dfERg-O6rDSp->g3iUo(Omz)I2rQhH&eomJa4UDhd*5hh_|OYu zr@p6-k;=g`eS=2aU&h#d!Vk5_-r<4+1ZI|oio(L8qQ)~b<@i7)nLL2HnB{<8tVosS zPQNrHEG^s-3sEF0dx}pK>0TcgTxE;IyS|M%SYXgvEQ(T;#cz}Yy5I3!WJ}9l?Kfn% z<}sbYMg9^zgu}PFcqu&fwcQ5r1NHX|ghzy3)(C`)V&M{(>yNCaq|764K}m&NM7e?ZA;Q<`!TXCQ=3>>^RRDd%Q@fM@w`~@3wSg5myfMhgL_r>q?{ki(BtI{lNhCOUBk6Te`iM1Ys z)+i#??A2ED$GVo51#Zv&^TcT3b`h3Ddyby-x+Mu0*8wbx&)&+jGl4p3cJXX6cdO8QLDdS4R-|PeEDB5d9)ES2L6jO$bJ0%U<-(|%cnjK$#?;n_~wl{HJ zY~K>dV=;)+`=4*a5H|XR$s90@TIQ1GHSykEdm8sQ#t%y)u6@U*(gnK1H-G=5ptpem zL1A-ni6QkD=9RoF@L@S>^T8N(rSUku4|g@Dt;UJ6&Kq$fytq6ZpELwzCN0-kIBz=^ z{{H+hncgfyLgy&Mdu#2Q1KMQ5Cm*2i(AGIlwF zLaNJn_YUuWKL18;rMb@?x_?7P*8=r4WtNE=B8HvXP9cK&d?40|Zq#XY~?JOYH;Reyj1<9;kg z-yuwE1oiUL)@SiJep$Zu@&xY{DOkAw%~L7)S=16`6($WYI>d6+r%(*tYpz+{2^p$7Q$NqZz1L*1Oo;wxXishVOUj zz0xCkX;X(KD9I*#XUW~{dFXo7Q17!o*Ae>K`y*Hm)wrI{qV)EkSl7`n6Kin)8b8L< z7KAB0ThK>&dr7*?&CE{eG%?5kQxE#?!$JWBvC!5`z4?I{0yO@-0XgPOsdqor=lA>N z9zyf?cwVUC0`krizmMjs-Orvs7Bv;4L55Np(5)B&sjeUj>PBfY&T207z+>R^Uz>5e z{|SY*Uc<%SQogMjnPl0InqL(a%4W(v8~q7PBR?jX^Uks&1;Mod?*~}#LVE0ya@W>Y zJId$ZWHm2awyZbxg=!iJ?Sl9CT<0X*R}U34Lx3zMsujQcZtT@7_MTbyQv?_)8(40& ziIdTr7?vU-_u`)-^Po|odx-OKBd6WhedoBed~j9J4*{mqWwCMq`HwOCGraShkC??Q zx;i@d5~SX%4!j%|7pErDI1W6Jd9Sm+@NlQJEr33`f4C(Kh*D8eVHzwFOfSjIROIhR zWxqjwXbTr;2rSM}VG9lsalYVQoL6@_cRCvx8??1y+}pJek$@0!Pr9urZUsuG!hhii zy@doNzxaC<+7PB{j=?v}rtuD*d5MeP404qKRbHJk<0xhNgZ+K4%f`$5c0gl9>UO+R zd-nWcv$~nk?hci!54nl@2Q;ZeM$G{?_`4+)mjV_Zr|45Pqp(gVo}VVW_Uu*aqA))# zWa1`t+Mu`-Ix3aaBM?Xka+U*jiOhw^-{)PAdX2X&XJQABMbCYyJ#yi(XRW%Vk%oya znGE5C3Thck+oymZu`Otki3cl$f;L&AE;Ie>&-~MZx!0S@b@- z9~zR)SFSVe&8&1?1Yyd`g-5l`oc-xKx6X6d1(s>Djd;5M1$(Td4$SKH}HAC7( zSo}q}-q`a}*nrY`dL;1*GsI1RvHPqI$`ADvSbgHZvMKTR>Z)-1P-ufrz_5g+?6Dm= z623B9sBCb%0>8Dmg?PLfzL)}4&e`f3jSel#T(zZywe>}IKnGA8P{cumNX7MSoq1Q8 zukqP7G0zLm9;XdjV9UG&;00CMI7+e3j?S>Ub=DVqJUoT3B$l!_ zw6D+Ews0>UG+XI}ohD5MU_9>yL-mbJJMxeAeSduYJ;dbu1_F-ZNjdr#~D6vF~Evt%C%;ha>OH zC5dPlK_$>lymT|ERMK$McjLOK`#3cB=T{{;f&7Wz-RgkQUDx{{?)I?0Iy-y)8t>ud z`-@dyJ?%zQ=Vks+K=t(gqJ*W;({Vw^ata&=5|8cH>Z#_7VG;DuS+)6!)xqjXfs65& zwuP2{PtSX;$Gc0R!@51$5s|9}$L8Bxp$8ITT;l1gdr~jkh2*_>Mjfna+MZBC-fpQP zf@9&3!>4{D--%X=m+a0c{@Ug@^n}fr#TA7_;%)o$RT~5O*mw-gR=4{`j<#|h;_+Vk zKRV4&&=67ioL9F;MBsnYv+OT5mRH>v+P(WBobeRWxVUV`E3=@Z8kTcpT6xTm$NkAK zv*#*+vV3NKcAkisxIh)X=WNu>8LfW7rd&*1;x7y zb?;baR95ZsYk@l-IJ#S7xb*BN5U}3$oKGOzczqJs>zRu+ly@z7!FJM_tz;%s)Vg_O zYNEy+F>*dJWcpjh3!ayUMm#<%{@0iDo{_$93=~$%n|-Q&)cmOLt}yBzBIa}X{rmiV zD(3~?()}0O(Ab!Svt<$VnuRp*7ZO1)faXvu(ya8lE^B%H5vYze-=-e@;MfHO4&Dod zwjuRTKr4V%^<1=4bRb#b(mGvCqwY}@g#?7mNAZqL=w4F6UIDcE|F)jHJeZSvTI6y0-2C)wt}*|* zO}*nH#*RW!C{WSRN;Mf91r~(E#&)bM&ExyBD~#X3fdF+bxuj9sWiz}vF#a9)7wmYx zopX=8_CtF;9#%sHwAXOK6_uQNKkLY1`rF%XMTCIzYm`)~tc0{HfaLmP-@#4$6cZm+pf?wEzj2Hg(C5 zA2>k^PGf_FLi2!<8vtmI>dwBjwEkzYy@UiM83L+r4xa}fOKQHVE&0|fCZKny2kl`# z?5|pjVSh+3DbhFUiD#N?Ix9MQ*jjqLzFm5FXgh<>5&s5+RJUWPynK9o^}Ko>J0=DL zz7O~5M_ya?cm>QLpnZ;u2PS?tV?C$2~r^Nkis2=u^ zFv^hV%;}sQkSdFj3N`G_z(SGuM*6pprZ&SJVHd&3!L+s*Ov04Ht5ef|#t(G_-R10z zhMW7fmhV+7&2->sUdsv3sYHe|%(HWpsS62xTC=da;@O zP;X+g1sJj7q{P0Gzcb4(%D*3Zyf>Shw0?L^)UBeXmr3_ox8#!RX$w$Q0}Hh1Tm5r4 zv(qq2Iww<^1yXbHdyd5G*e9X?dJ6BsW4YytLJ4WNy+kB&4y{y(6;fzeSRB&E_1Okd zHwdM=y1FJO#{r!@^&w*8eu?ZDwLR~M)0fz4^j7zF>2&taE!3!ttdm>!u)Wij!tpl(t7 za&xB4Q8AH`ov|V>@6vZ~k*MMB6)(NT^{I(ePFY@_S_t#T*2Yc0nl}lkve4%sL70`5 z**Pz4S-0(Yd2Cwz2SElmn$kpZhXN2To=UUa*p7@uK`=--^(EJ~S=`vs^#blHKJ$-~ z?}y^!SHEP|+{S|wExRG`^>DDGxX>88Kn78GKb6nZV0QP@b<&6J;K!ROp~uUvy+2XF zNp$BbCM46{?aP+CJgrI;X4J=nnHdehEZ_0!eaVcro*v#b$292wsjsVxj*baTDf{~M zYvF$3qV8End+-x7YED)9I8`-0tkk-)%uMh&1ry>Z{1@BqUaRqzdmhlpzubGXmjrp3 z%n(`@J{U;O8Q#V^E@e*cpkBlKyeYk(g~uL^xOjbf-Y4l2=&0}X|6uQPeD4n$tEWl} zZ4cY1cvFWgDjRM$9~bqSZI+6O!MXZB*wUQQWfX#H~ zm{3e)=k$plE>Jb6)m(MX|}QM;1v8N`X3l>ja$FL#c!}77`TH)VWo~hk$Y;W_69!XMLshh3-d? z(g)NP*;9L`NT&hY>hkh{cvj3>rU;{&N^-OttyC|g*D3I_x2JAEWWXI&=jfl)AR|iQ zE%IPkSzT#!eI-&ory{S;@4abdWcN$@2+fUF8dD)~ z7O{?yuS_LF$Wf$9VjGU`3Rz15PjwzjcZ9L=a=MRB^DeqAyJ3T-eD zFwgwZbU{be?Nc{?qVADTr!Stg=-0H}8XI3&s|{J+@)uv;{hfHA&O9MpdFlsj3F=Y9 zMW643f_ujN+DQtx$2a0whfHPq7{#${#l+^oi|Z?eLgF)}0*rD}b%Z3OwoS>(1M!*B94q~34KcaBYF@@_;ON;m;BLf_QktDE@tT@`b7U?RQu0(8VmH{5)6+E&h-HlJ0 zklQgTHa7N}OTEyo6Ug}c;>#8(qT#bYACwtnPUyF)0s?%z!R@71Gi9;s#wXt);M%vg zG6T1R#xMQW?0_pE_5rfA$U3MO7dF*=|;4W#f^z1b%#4+QWW%b9g9$yrub3(>*B8Syb+}!XIjR z)M}59Qib`RpQATl6wx%FTp0=Xe`CH1MfWumiH`yKkN-IRuV2}8g2WhJFbY17*;Rfq z*B2v1e|g#)z4~O;MRseCB{anJ?pntUJ{PMg3l0WbT^`|IpVw;298IJG9eSfXr2!nDxLpU}a;w zcNIfRzYIxcX1m~ixLSRy6e%)~*)qQ7cF;Jc!a;4{Z9*~d_cgN3U^#u%wHBbwoUW~G z<;p#j#!HUlfOU|guBEhKy_=-SUu3s?eihKML*?jjMh!}T0H^%a4|I-#4DNbnKH_Id zD#y(n6H^Y(ao39Ko2@)r*4I3PYcAF7mkIjtek4jCN@}@)vU|Sb82iD6``~6%&GgEr zTV1gDAW&zVzqs}yiIm94=Y9PFJeKLeH#i7Lk4@J)=C$w41IGmr(7$+b-P4Ya7?mp) zw#kNK#OmC9yLkJtyXo;E2=u$2@uz?NX1C;h`OM`Ss2ry9Xm#0ZYisW>J=`QPrF-Aq zF5Pp|(*CH=qp_Q2C~2T(lD7+S@6b zz$UN)p?v&cy4R8C61d^2=7=XaIE)(q9MmWj(nMe{wH1CHmw&CMB3a?OqvUD<$TR%U z>#e~gcazos39TOvYnO^Ny&Y9d;@sv{uJ^~FNt&9htZYE>3?NkO0I%7iuA``Nz@Uwg z`));Z>ROGOu6t!(-fh*Kt>@t-RN#CVP)(d%ok1U|ScFP4%N*K+P#>a#(TS-M91f-? zks?=XmxQXFcA|?{ES*!E){88$w={1OJyLwVPKHVK_}z|0jZ`A?e|8z~+JEyPQsKyr ztX8`}>HH+*Vbk4;9nl+uvPuC$h2jVSZ$!s`lG>jmE)mpJZJK0Bm3=m2!To>v1VK_I zS?J+cRTV%%W;s1%26SZahQ)bS*_vp8=Ap|N8PW<4E)&zOp|t8(ywtzUcfs;Mc?58Wy{5cypvc&M9MLSDm!q{$2uhRsGAwjj;nydx%;)FuaQn z{T4Zj8cIsHn{`dvd2&K?4YrRyXrm#ZEatX_wb@vw?*}RxcTEzD8$;tbTK)gC;nq>qc*)2Jry8)0cTUuC< z!3cOyy?1cny_I^2M#4|TjRINp@VuAveFy_#07xqUd`%pPI=289s_(;@p4ZKcDFpu> zwnV+@JQQ8e$&GBc{K;#Hs0Y|^3S(Ox^XR>U)QcmqE#Y-bN@{A%4(Am^b9LPwNB z5t`=v!J~jsD}OnmYo|Y}FF_v1`sjU6}?&rt`tD3}r;`2_-7aH!XRd3}x*xtTfbIFzkHcvxN=}@H-t3gSshI&eTMw zsot;n_hAQ1V@jeUcymboGU(E2#_!UM@yV-TA%wqq^=_=Pu`d4hRhs(j;#NDprl()t zA9>H|BbefUp0K#>7J8sl?z{fdd;STWhHt&R=N>ZCD-4-%S6Hufulsb7VMTVab257%1qzQOvjM9JBKAW;%p~97%@IW>B5V?Z;A3^_vE#!pKD>hhRDjJ+I3{W)6Mj?ADok zBT2sUbAso^T==_|mUkmRT4_U**nABXr3l0nY^ss{CR>s(# zw;(`|#q@3fLKj8x+4*tW^Dmp(Als7d)C5$nAqAbF@omE|tmgT@4oSx6w;^`50*B~} z-h0O%z4N}17S+iYqqCYh-+;_ed@glfJGtOyS6wk?ai%$&NP8RM-X19T9PY$)6Iv7) zt*&xtrqK*O{-)i~-$JUeM*LLSQXn2_P+)P-l(#?126Gr@`$H zJGl`OXoo_szn#90;2Xb^${F32RtXnnHB!yj%-Tu*J&qWY&qmFuYx}CIy2@?-a3m#` zEX2QUb^Duo@B*^|{=YWlHiJxvojsA7iv8l63ydGw1V0K8BSS`a&kG}QpTqU7mw|%S zP+I->@4vVOD8ja`hrXcsHO0QH6z8)XYKZ1J3((aRuCA_na{TOV2MslodPAYvZ1}uC z-3n$@D)E6$0x~2tZ&16&DeyhB+`ISmsm-({`k~@k*0#2ZoQ}U!u9463aA1Q2I5{TE z8Rzg;qWj&yr0TNffiF1^XZ*5O$IBN`9%&aJTX7y|X#-;3pyg#)>G-@4#uHPMZu~Zn z?MM4&Sya*GA7lX|CB%+56&wJ9q9M~t&=c(9>>T~feskSEvKs~h;y+Gi-5gbb@B3EA zdmj^`&SY9LH8naut*!?T;fG37Mt`euo7^fWYQn)Hh>wapaNtGXpV@G!hqTPk6^!f% zi?lb89MQ@VfEcj$*R)}!s!FVcsJLDp0^VUx$ls?mh9=N!hwab*7BEp|7Eu8Jp?8RoQ2 zQpqtVDUV#?d>mN?c58qQ%@}s>Ebow$>KPjRpfS03_H@M-4)Sa60RH#kVN(OX5@7J0 zAV}M)m(hU?TknFFp=#g>dw`A);hb}~M%A-lh}s~rV>Oc)gS!PqbVc;XaLCwqNuE1U z{Ha_aIyyIJRIYI!>{LA18CveD*MB`)zPjQWA8|KZT5zImAk-$W`xv ztX|{YkuMQX&C;5St4meCaT(YmB~$eqYchn3?t7`uC8R(Aehz`xkF z_*uZB0*gk{XQp>Z4jhnwEV&*D*vEfBpGodv&!Kt^PMW<|K~X)pQjN^-=;H#P1(z{; zu1;e*+M+`pH%vY(-YgYN;1!^B>BmXILNwgn!8lW!-OS%x@k2;SFjvxRi*m#Or@96c zfR+LV(FLZ$=f>WQPoBL!?=(|SKQi2at)4q@sgEQTFfRRO!kVaCLOQ4c(xMD~{dcbL zMwHR3=4`f28!n$-*HqVgUjAnKSgXKVTj4oeVUQZUHPbB54TyH2nZ6xAU9 z^Y~`8pBO47#JUG`eogP4`JA_Ue!P~^;JFS|$^%MbR`*t8cb)z16ffb4;FixkT&?a4 z0ZB;jX&gb3OZOx+AXLZawY`1L*>i=88VvXUxpZ*lk`tp+m3)2=fVe!sUxUpw4oT;s zpzPaVx=#frL^O{K!QrF~cO^>U_Hy5emzW|&jQ!xN6Ys)2thCeHw*Z;3dRME|{l%?8 z*Vop~czl2K8Z?Iz z=hUL#pEK!TV&Zz+9UX=uZ)CRTD9%K0FjRWn7awSW`z=5`P;uwi988w7u;j&?bec9Q zHQM;a3aNbg!|9tBkZ`+r1~|WL#hFYKhVWK$(8J;BVpWb74%v086YE!{kL|meO}h7V zsav?G+Lch{cJ?rJDem9kt+17|9?WTBUdgCkIFu8dUtS`#-%P3Pr893Uf88b-qcmzd zzzhqio}+r!O&e;APuE{Y61mmW>OFy1Qe$I}Vi)(fcTFD9mB&zGsYD-_gZvymIH*p0 zC`<(xLe>$d$i}+iQ2SLlE-nU-goHdmlb3gnE|mV8V)n!iqW}B;9&PVE9rMJQ++x|} z!CYjdq}W)-fkJfFb(yr6IN78Op}9(9Y$gtg%Jiw)+$vckb=t+CM+WK+py$e9v*yiJ z7@g5%9zTZ|udmao{M^h9THvcfL$lqGNppClh#dT;va2UW2QVZt(MlTWwxCFmc^ogV z+%#vbNE?^PQ~T^KQm+jlezmFA!sl<3M2yDhF?RU)^{tpftTuBVJXKl5<_5`=&HsAX zW`-Dwp=O^&#}Cgu(21uR#+~ql@=Sc$qQGqy#h=WIlL2}{UztP}(tdlH#==5qiI%Xaj}fYMEoXnzaT3!V z33;Pw`rGb9ts$D)&Yc+WW`xm{^*zO|Ys=VZ0P5xi5!UX7hqs`fe#uv+O0%8No^5;p zH$3UOyq{5reEk~BU*JRnS%Fqyox3Dg*<1vUMX+lTsJIQ#Slbye5@^KB?hkFX<$TrNriTYA`QsK5T|2)>d4CZ2iZ?s13DKz2Qwk)nHv92M8LnE zMOe>g?86`;8rrqfn0TZ_L(qvdqMp1FD%H~|8)fZ1YZAgaxsLl3IBBk1^_@Mz(fA+HITEH{@eOvW3t%1SzB=S>iu7y zW(dar8E5=oeJ_HH)xScN|M$^K%Q5;|}6&f)yV0tv%z$h*dQ9A>%G-B*kyzW|B?_IciEMs3fH4>N8zvRhc86 znWK)ylm89ti#fo~VmHOofP0(YS+vc&tWhwf!fYe9*1n6?Icn(cgg|wO|D*KN{ra!7 z`$jZ-_`e3I!&f7PnNgZSIfB1fXMi9jBbf<49;TYa;<;wtKBe}f7=Q7p-!{hX9)q$i zzcuY(!spw+9&Vf9Pm01wWVCga+DTvqTX50KvhpU_)k63}?Ta-m(u9&wgVGu3_aPSl zpOdeH2R4wI)vw=^s6ld9SFQ3Lwj`rWiS&4`;j_{Cr%U|VMn9V3j{Y(ePDT2Ee461O zcXvJq>#X+hoOv8Ch51>flr7E^2_N&)tGFL z4dxw1aj>au>cYu-_EUhnWusZ+=DyRA<0yqUlqBH0d#;gho=5}*e*M$qRim!bYvg#} zgS6nYQ|hU4<(UH)`%BagkK_)SHMyNTs-=fkD2~)b;3->sWw=~{ZT)TXk~`=Hjr2-g z(kx1g^Rz}X7sIE^O5*owrT9COlTi?eSxiVC`f5okwU;J220=-n6ki7hf!X|>$oP=uD7K+pzc*nq4TF~Y~`$dMgI@1Gwfl7%r6Pq zdN^_27#jv;P~2u=Dc-ZDti04Ve=+0geef}5zSpDi?MnkM!4l}!3U`_TeuQd5baYx` zqUGz$r1z<-6v268@B&voTzD*vwZH5%rKOc@ZC&+`Dt5{bn~p|!a**5GDEgogILS4< zh=_C}ukCFT$_w|$X(_a)cKjuN}BJ?I9EN)c7V1O%Qikwf#oznbLO6M@Aa9VYcxRgY1@UCQiBU*= zGcMd@(XO(%NYyM_TyY}eDSKq`y}2myz0O(^yp379+m-NjJKTc5JSv?l>RSGqJT)(v zW0rKaymIl|iBzCrY3qzW_UEcO)w7Yuj}tqePHFJQ*sV*?4;RXH%(N?H!ro zQ>x$(-*`f^LcDP5&|5r)PMP$%i*J8HuFvECEbmA1n=>545E6%FMGgUO|CZL1XXpXp z`gDdbnT+dY5g@2Fn@VwXqQRE(eRFm?knfcIW1o3p-TDE6!%Xj^Nto^j8qzf*%9cSg zOMiqdGwK%wV$!Ozsj9-!uN4fH4P+olT|xyXP0XflJ{jb2^FjvVp&bqsAN66-Tq*cZ2X zHKkonty6Oif&ISMbIpUyI+TZRj7sZ7U#|~+{$J2!k>>APKY4XEeNS^PXrL<2A-53W zi}78oz<*9*F_L(V%`+zMC*MPnt6;FjPw%vBn^u3Jr($mYn&WJER0Y5)#SF$YUW!+>=EnR`;_2!!!_rqMY_)cE!ue1A zYOXrY&#nB)fS%azqlFF9`C<9?GAp$YAGEak{WNU8zt%avi2oLyJGLijQ32&77#&^B z;F9CFD?Dk-8A49rMJKYvxqRaE|A(7K5n}txbVlI%oYWthEeEKC5`W)ap2!RgRrE)t zDPsQ4aw5*fV$ed<+>m`z5Wa8|iN8 z?uI>|?|r`a|Hs~AGk`(eHw)HWYtDIH=XsoD;RPdVwAi+#OsQP0Ll;EvW2(0qA6L-8 z-eb(~y7>rs?9XfwW??wOO`-^Zag+n!_`DHaH_(^Cry$_dP#5)keK;$!cHo|cD) z9wLF zPIV1;1Yu1zclGHMaTo$!#{8iVOsdg2l|AGjcwqdknpunZ(*Ks$jk(Jx^kCnM_k!|` z=a_=KP~}EcpB&C|5gOtfH0YQ=@@CHwdG$h7=VkVctykY4Eib6#SAz}TuCoo;0VXpo%i(*j8 zE1HD3WVK?tlZO)%)p^i zi}mJu&NeZADgvMCf-<7psuCiiF5zizPSYjbMG?ZRDV!!2a$U#4jRBh+$8D;(*ZE`4 zBV&g-KC@BF)j+_-=Z6EXK$&=7ukh0aXc!sNAK!v)2kQnk2z>C;iaL3KoC%yv)**QRAztQj8y7)F^rPz9Ua4?Mn^@+SlJieH0VFGQA#Kzx3RJ_ z=jE-dnBF0*HTKV$lyd#bD+I)YwF+8e>F#y?OtnPP!a@O6RnPq64bOt**Dwr52;|0? zIUBJE0Vdjpy3V#AHO1w#SI}iuYL?B8kFBr>zIK7t>I6dUrI%i0ZNisL7@034lz@ha zr1$GhuA_K)!0C+s$_KV|3pARNox4+1iwJtks^^8;rl+~t2mp)3`V$F^das7#L3s)SN)P-sdt zVt9YPSns=3xxLkao1miYlT1y7RlNo6DE% z6zcjLFS&lLI3p6?hmY!@&s_}8heCEkI+sxaRmCgh4RfhDK+@8DObz-u!3x!YiHGTvRkxv@jwxGKaP)ry6LjXS`csG+IUtD;}+H z1k#eY8}svJ=bk`xPJ63O&;IFYzq4t*JC7rN)ozRr7gBfB};p69am?pX#rU63OsJUPV8zN1L%o7;TECPB+<) z)qVT6ODb@&sC(Q%!^jB4u@NOprrgU_hxxksqd!zXe4eqY{WZN%zWlN~d+g`3wa=f# z2$Dr-^d#wv8`TC3QRk5p({&wAx>j3`MjtdwntTVU)Ikv=?oY&N3gYXNG@b@iX$e(1 z60eQL`X#rqs)YK{lxF2TwXx)ON*E#nn?}3Pbj!cLE3Q`=R5O} z>0h<#30v94fIZdva-g)_cKw{HvD#=dU(~rrMfrYuMh}@tEcS1O#=oy+KM^3#8g81uL1Lc&NbJDUEh8=3NX}^RDrG!K;^?d1e z*>(P(Q>`E?k&GnSQdhns#SkV+#;^vWV}!_vi~APl0)2XQR!ql0 z31o@f{h_2j(7^!P4-F$wX!4+PF3LE5w1$rs^SVoP;%m3uk;^AGNCjwkT;MH80{!5`}W!nM?GDMiw>baD5>#F z7#U;u0MdZ?j(R!4Q~(l0j|?NI9@_Go^_@N+4-Ym(M>jPMl^uh$&Cr#^0;Nr*J;|~gd69k#@p;?XL3SrFeqzndQu)po~dO}pBT=7XwLig>;(M!SvAe0 zmCC#Bv#y9h?avpb3>wSSBz%&fkJf&$5;ARd1e!Idhs%3zO*<@&bo6}3f4(fg_^k6b zFJlrDz5ua1hrQGH!eZx_V_PY-6PSRsdXFB}RbR={nfslA5f-2Q<}pg@JT6YIL-1QJ z2aK(Pysk?BF)OJ)!%4*c6^r&YpI4}7W%u-)FKlhDbE~OO7*5et=E!*oc#ZEAN)CY~ z#Ga(-gBMoHB*L;mmnskViv4OHqjLC1j{3$!*3smuEmHtsxpQ+Tg0Qb4HNE?kcoG*M1`hO$KtK)+3-OfVoezJeNw%A2T zd;eMpPI{)A*S@;ZzS48CkrJohBU|d1K2=~IVyG8NgW?6o%Z0+{kP*)~rrUT0cNj3( zk)ZNFOkkENS8#m2MyXpPX5LXS{LL&h4ikUk+)m>wf{MSszx4(p(usaHQk*jlqQ&Sl zcD%fsp~!eB^@^wOeOB(9tX}YvhK?^hv=T3NL=b#d+5m3b%?{*Te$1V~r*gh}AG|kd zKJ+&%aXVkIx&BoY?&b9lo+ubd`IvRBe)Xw_i@e_1)I0~%-qD`H%XV@5-E{Qlr=bG( zlZ9T#4O3I9>YbkMUQdBCrc~~K2ypi!)k-frhJJST)*q~Es<($p^@Lu+a0T*1guUFF zw_YsJ@+GOEdSWHuVs1$qPjiQh_2ba<0z6+_X*302o8;jo2*yr1+ z#_9shSQQ)=L#kn8cvS7iZRP+<1Mj^PzuPM%aHw}Ze$RWe?T_ufy-iCkbk)F&1E7t^ z*~2AEByoG-h#pDDUhKe8y__ComUtgYNV2O?F}8Z`!eh&zQ%O{UokL?CC~%e7*no1mzm)xzRTtz2Ke*J9i!8GDr8jl8)nNzCz9s>BMgxvc!_wU#es+jeQ<9dGIv#EY(0o^Tk@E~?kT`xguttNe(%nze> z^16h2%57@xSAS{4R}IuXL51v;6-B3q)U;2{-Xu_1V;2)wG;ziF`2u^ng{f8i)2 zS*no)2#iXlir`D?h<$^4`_)OPCISg7eff7ye)aJoK%2RVw*C z+=7Uge>ASjfQP?^!Qub|-NzulPmqt4hZupiZ>G!}zqMgO)%f2t;%1RAWx%02vLO6$*flul^rD_FB&PsLshUy`p~i4QII8ASy1Lc!^wHnKUi&WvWcTmR1>Y}}rV3w@ zZn^Q-f4ErxWwneeQH>d!$nhN-SA|4j{We zo?p;fZErgL^F?0@_2^=iIARYiA-qRoPh(g~pG}yPS(fG)#6#7}HUZB`*d3kKbcJ@= z|Iwr7&^&kY+P!)eQm~~^eVsyJ9bD=mfiAA%^Yiq8v+i5-I8&b<~{sZe<2e z2eF?bLJtCXRtldJrB_;WZ;liAO3JuqF zv$Izru($beL8nF5A~N{x`G^>0?Wcd-SC&j0dg_CxdiYLgNU*;kdHJuTq*M_Mi68bk ziX+s;@4mS)H3Tx&6`PUV!lDiULefTyq6s_I2&)}1ZOXFE;SFBsnVX0B$y>`^jORRP z&)^c^{C0d??|Rs`V!2Xs)E+4DB#0c{bkj7T-SK2*XE&1^AUgY5jA_D(4m-YReU00N z36Dhog#0>3HV<}fa|4US=da9*t>PYeY;JA@2Zu|CBzjKE+6SRW>tB^wZLO`Gyi`xK zevh+H(E_|VCU$F1?d#Hc=RtCI&%c#GCgYCb{bIQN(^I>>6iURdKHB#WY$}pEhMG)> zt?Gs)6_?jV(+e>b(vWXq5nG;ZWs;9AoZM53Hg4%F=olEpm;@v?$khua>bTuK&)OPk zCAj_0>Gf?5EB|XIZ6l`^2@EIS8-B!}+*vuiXox1B+i>G=vD-Nwo3Wq24I7zg?^i6G z8U9gE&s6ZMaed-WHN+#seU52S=y7#aX{A9g+gjIFT|0)2gGa!t0|A2E%UY{3J3W5r z%I}$BZ&{KkZMr@l7ibWqC#Qm0-nZ!r?06|)R`*r@B}7|O(7bF}zfjUjDHC&9F_w$$ z16hNF#)$SnjdvU%tkJ|pzF*t@t6n$6hRYJe7(;(L(E;U;-NNzP3)C<-VAlt^Ul}vH+Svep)2%BNreyP{W_AWt!=!=|eW9oRI!03^Wb0(BD2k|+-Q^!FxmWIW0 z4CwBee5PTIf#os6?dhO@&WxM3y72J9mY`3Ng;eO2GAD&+Q}(Vsizt0^DiSSQ}?Q>j`w1^LK^rd7rFLy=Vc1IPOqNn>dflbRPC5{v;>WXOBi?x_FRMP?J1?L41v z+83Iw85C5&CUV*JgrfavviY&bJVQ#8kuEp&bLQ#_gy-r~SuvlLMO}?k96g zw)>dTggJHF+bb&uz`gxD-cmIDEe{Bvo!D~wM_Uf*k_PM!cIfHlNk2D9W-QE&*AWm4 zOG_6$10q>fju_aXsxSPm5t7la->MD8X1zcEr&shxv%A7E*-^A`CZ16bD>F^sz0&4n z+Z{$s=L@-UoEb}#Le>n4aK#na)I3XsGwxLDGCdm+mtG0@%QG{>VPV8UAln&=c{(|2 z)@fYDLtDs^5lMfLAu${>v4PVz(Eitne6jhTsPhJ<_rVmFv9ruf14X8Z+>DY5y#)FA zy0JYkPE*G-naJmh9Ci?&o&lNVn#D(`4irpMCAL5%H{PH@C0>hBHj3aSrE|m*G8q4A zy<5Ne?BDe;dM&s97}_551$qnChkwx;O1kt)l9S*tqCOQF$m(rz8xTsD2FlAca3&#z z+|hNE!W1MVUFkIwF$2G>3om@Y)LsDOXLSx>5>0ZXr=+|!!h=Z5jWN^GQp01y2kgiM zsi?Diw~3bhDr}saQ{KsxDpMX!Z5Pi{b0lJjV=x;{D^^DJ;HQf(>a?Un?$Tmx^}exj zp92f_<0}sVg2*zHnU;?4ntf)~(EgH(Ni{raD;ai)SDvjIXxwElckfo;EN49Rybud6 z)z8@iP(@FOpJ2oCX#J|kUbB+W>DK}hgPZ+!Yikw>$)1(F+K_DH5Dzp$sOyZ=HTZCz%%gN=O4rSDi%e| ztL2!53<0SReU6>7O5e#^$6u=Z_Au%1(eR+a4W(51N-$Yy298MS12zTmqSVjIO?u(z z9GBLee+dP?65rY}A{kT)vmJUdlT|!jPH0SNuJ7bV!vn>;w{Q}4yqj-6*R?f1lb@6y zaquA~Q1fu4!v(LFi86VM0;Y~E$JhvjIY z=c6A#ZW9ypM>1^@(@bU#??j&pm4p}8Di(p6XD6N+o`|);<-N26{Ft-3Ql^cqq zn&=rdP3Vr?!1%|<&W_)jxynV9u~0~^%?i{RJFa}TPF9j1o0Zvz$4vIC<_|Fu;(q+V zoMY}jcey8fSq3HSH>A&30Bw<{(y08!`elXqpA|CLN^Aa_`syAC>knp=TE*Fwh4b;? ztLNzetJ*{(p%ZU9a&j-70U~Gn^5st>Bbn^2xoY%DcF!JNK&V8IY++~R;JsAoh>)#7 zf)%U6$(KHDb!=h%+CP8WD}Zc+n(B2Flz;yZtpwTmMPn;V%R>wMqeCmz;;8}4y=)_j zVhf_ZoTt10;{!Cr03Z)eIwsxH=}g|L=GMISj_PlLW)n_fONxEtPpRpnP_94K2z&r zWc@2;ZUxJT5Y&QXD!DObL zLPLhI)O}cyOoZmKp)}r#_na~xd>nY28dU2IixwxXiZkB{;~0wc z>5h$2<8UKEp=A_uU1*Yyc@G^Wdpi7@|74RD0!raLelp_@{QX*^CFw-}KAQRe>PQLNXLR0Rd5f6-y*Czf1xl?{E}Av_)* zqo=J*@yr&6dB2QPVPu(jYk7#PxkOYJ}N8X8N1Mvwc4(FV;v~KiO^M|=eh_kh^DJ+@1P;P$ybJF>wbzP1>s~e zdmT?yX2U5r)#figH!#unU6QhSlFXX7EhLl5)|8%6Fi~;RczG&JHDIMwd*dre$*3oQ z{n4RqdJU(2DuS_Ar`h>|X6*5lFk0B9&lqj#`iX}0{f2$W)5_96lc zY5DivuKbiPJeRUQoav-j=2b4>5frK%FzfT|T{Q&dMZGbVN+rAx<5Q)4L!8-pp=W%A zPIZdE#{SJMc8#G?`GK}7B>S5I(|Xy?RVx{8;_`f*_UF)~nOs0B&x-*zElP%5jHW)^g69zn_|K4i}pIR)Lyqr_nz} z7BSE2E{qc}S`)W>m4uf;oqlmacXJa9RA>JDIV~zeva9#*8L5XQ6w_1eyFSXStK+zf zuKnTt#z{inCQYx*B$qu)+DBAW)SDrnCu`*-g6Eke9b#9L4 zx9z70kqa%gKU6vbtVH8o&;@Skui`e7$`sXi&attRVFhDRQITWAgNBXwqZOz9!3+D* zTxFzbunWt}3CVG!#8^p&%0w9W>B4y)Bg8kfZ|IwsK~oxRZA&$fAb~+rrY1WCk-v@B zKOlG2)N!ELVT_b;<2j$_i%awbNl6x%Z=0CyAk_bTXOci2ziKMsuwEpF3l{JhLS60Q5q`1;z#de8F+jW2#K+TZF|#FHCHWJVKezW zT{gWB0^!sRHHnG&>FiWG|8C#|0(cyzDh^Y#=SudLTd_KI-1M}DA+0b)lPF|&cWe9a zV9ns$XQB-kPj{kUf-Y5imv=zz-Q<%`Qt)SG%8J(|doPDL;lxL8WzMScCQSIEJ~EMpFj zLKGJhdr+avr$e}qVhyG?7av&@n^?WFUuAr%pM8XJEA$j|-cjalUAeidX(HcR^*NU4 zWg&-0RA0K_i&0QTl(gNqjPZ+?LA@XUP&vTCWLenW@3axXuH%pwdnACa?o;8c{M!SA zDXKA@!12>sGI>44B_bR!DX- zL$#%9lB{ixIU7B0VSdbsaDehB+_hr<@k#}SgmXO+GK*BDYBPl)G=t)6y_!b0_jlTB zq7WJlMUSF3Ex6}dQ_v>|$39mn^Ym>JJ076VqY0rIn;fd4IltC)8W&R)m7=b_x$}9cBU>i0I`k^lILPfbiIgm!+yj?k$)QgG89j5_V!io;{~jdJ zBL;lq;Br|ITuax#G0L{LC87KO{9z3Z%%Ux7ZuVYGjJEuTs{aF3EKB1(9Jn&Q82jc$XM#i$w_$^ z_bhpD4?Cta({kBO!EwGotXC!M5+sBsNoO#TkeC7bo&-Un z>ldCwW9eY6BW)~J+OAoQ1k}B0-@oUm6oRVTdMK9EYa$7XiNy{aCvR!%x+r3-hc z{pDZ1o+e717kbm{6avEMt9s#OcBdWIUdwj-#ioYMCFOg{+bm=gvk*{cu&ew8-j%{})lcurjH zWwljVh_Ua!0Up#7?KtnTlqJ)P*rX9T5@uJq)4jJlqjAjtE+#0g%o3#H~uch z?)$21*UZmGr%wJIavFkmyxL?M=g}>Gou`)v4*?UG^@*o=zH$v0_sq1$gO7o4jHAk@ zSd~H{@B8lXm)o57z!{#i)DRajoWBIcn+X}DZF3BE68|}4Sz}OQB=C_aVSTYf12X(+&uGb9^z}X6@6~h zE?vm!WYS0Xp4xJT)%)p9XNODrnn4(RB>v6;EE&A0B>HV=gMr6rm*=8Sh8z%!qE6M_a~(SK>G}N1 zn4m8|O^WSBy)Gq=GGDD&8x8&UKXCx3Nk<-t-sF{h78`&~&8dS)EV?)SKZa33jk?OO zr52YNzb?~?ufn3=|N9W@|Ci^pxpN=$|7ec`dwKtFNpn`Hty(cQz9hZfe+96>C+gEd z^#3bY{{PB~XMjkwGlpSOMu);qBB%F`QSrg^zk?<#6b)EV6_6tsb;u*J>$BO;n^FbK zBpn%=X4p5Ws-1o;iOcBW5s)BIvLZlbE66gVHi#IHdkJAy@GYZ}j=!u_t@u&>_ZB zZbU(7n7s@a59j6U7*)tS3hs70hI8SCFm>Akc=JP#4E2>=A<}N z?Ua0J%S3f^s`gyBxbK4_Z z2Jcl~{#7#@!>=ctWdtYwpXUoV}nu~m{28Yp{N z{+s?4j`GDy(;Zezk8fgG+8hWb^ck)9woGW2vKU|93>vChh4&~V_4M_Orf~8LF>7Qg z$5IYBwhSGC;Gl(8b0t&t1dq$x3ZMD&`D)q0p&`T1SL%+du4de%INZKjGfQ5&PO|&O zEUj}B6VMP4K?Y*cmDNpqyiZDS(VhZKcK(*=_znS@ALx}(9XB8Loa{>)B=e+U;kKeZ zWoiERA~FU_{LS#it(ryKjTweBuhywu_D1-%O$)iK8qSEixDI!xL1smxtvtjDLdC^R zs#YSUYbO;5`AF206a*rIAtU}??KDO&-?*xV>BEHar!B?L9on6Ai#DEORk^8f*{N}G zZu>0so2WFje>Ia9xpx6%knG7n`A^nn$e@uH(_;7jqbhJr=O^<}(h<8*vJ#J&!

(BKV#od1VCuMv&8O<+EqM^91)ZQWye7AU%zam+W#giE9=hl&XH|g9hb#ZAV&wO z&TG2p;iT1lI|AR zvJsed7m^2DuAL?X%YGb<-o_pOaf+@SCT{7&ub#wT+*i$G&v)q+7crb?fsi3&yyb43{(^o?U!qAm#{hf?s_Bn`N)|OukgfeA~1V)48%n zLIL$wR`_ovML78DFTYCx!b>UFqBr5n%lM@5XTTT{egP=B%boVe+hp_S8{nud8;zfu zf;(8sj%%rsLX|$=TB8&Z z1*K6<|Dr%x*l+ibQ6k~#VD z4AeDK$so)^zwZcR%PCoi)`EjK)==SwQRSNsYP!v1S38=`f(D%xoWH^%{mbbI44e{2 z*aDnVz`yGl;{c4Zvj9`==tV$QhWLY+5W}bI8`T2+w?W;TZjmv)c{KW!HF=@xnx0nz z=So^ps0A&#&?&j2fTvSwf0w*QD3Hc(jX^3aJI@i-a$v zrJAq<>&FYuAR`d|6$TG|B*z-hqMF8}xbzzWsmU@5eWUo&o`U_45A7Z9)#sAs)PYVG z2siM3Q8qKf$say^ustGv@!mv99ZC6~@w|NEb8`du*Ej7C%Q?{kRW<_?s{#)PElX(% zq`nrFIuoiYoY5+Vh3)3PAD#Gjmi#guI->*udzv=kwZcv0B%wjd5=DAxGUh zyQ94$6chx5hL1v!;Y@C&g6XxWjek{624HRzlS|Se?2BH?+Lo) z-+j`*q2Vt^%_OKGyF4w-S8~(PFF6qUTsMDAq-@YeCKHPv%_jcu>^R-Ur?(ljcy#F% zGWX$darLR)ltBYpMAf(}c~Vna?Jb=OIsT{0=olGFsyTM|3OEb=TSU{+-|>@OlR{)- zbRkhrX981qH6$6(0pGHih)X(qCLv@rzHFG*EDYA?g*g_*Nd@w0qSAw;q093*Pko5$w%i8LLOIbQhMQ_}rT>`z6GpX_~iC+{6qLy=Zh zf3L>zJE=d_C3k4_o#(_gQ9i|oiDJqYGsXRKovrdNQ{z0|DpaG0_>bPa__)f6a#Bss z$x$|zQdPM$flhP0k{&#wrT5zBk}z9V#tEWSEMaT;{R^>Ff~6(09`Inu{C3%rTU4dW zmtGizvRuc51d!k2WHv1nBw@7uPpFdUNXhy_j)gAkR>R+E-8(4tFzJBk>{8T>z3snU z#0;2PA#&xDECx+l)CqQrO?mlsT>S4IW^`wFUHQsqyByQTEs)XBU;>1FZs&UBlE`z& zjg3DIn>j1k9x>G~IlZ*r3^*s^v3s@hCf>$H<;8JaGY@9b? zM|f3@Go0ynv(TK#q|fKKvIOX7^?e|d3|}iGoO~dG!LI3IbTNrpo852a5x|0yhNhP$ zHvFbEiW4aNySrhHD?a3@ZEtNm5!Krs%%m*n7>W4k9fD(w>)N*)uV?pE%kAXn=7Bf}RLunW;z=gm&yyg+2mb53>Z)e%CeSF!axZah z_y_y_xUkHiv7*OkZ(wKeMX@-Y&o+Pdpv_^uW$Zw`m=mZ^7e|U`hYcHkf#wVdyliUH zsV^4xQbZTuYw@gKcAV|(kpqEFBO^m6dwU=j@D5HHo74VxC;zcdv%~mC?7VY!b`Fz< zwTj9_jBA5kGSe6--nvs$3&5#keU1vBpz6VY)Hh8y0!(wrA4{jNQ9*DhTdIy#Wy`f`U$1M-eOKQzC%-}s^dZgJN~JidAJQ%Y$3^-0xH zW(~U?Dp--0?h7W(K-FmIp>UzZ@>)D1A_p;iCXtp{_d+PgOCU{gA^Z`q{CDA z-HEm1K8g0)0c4$>K@G&D#qSQ0Q9w2E64;*MSy^0xe$(3zFfM7A4 z{Kfv7goQfGOyNuN^AKj}0>(eQKv0AZ0S)TWp)ZPzjqZKslQxAsDLV{-_z!aeYx(A3*XJj@EB9BB3X{DmI#tB6gmm9C!eeb#>3@T1^8tJ|d8g_$7oSDl%Hw zW38k8`MF-d*)2FYMEL%e`;+lzU>C?@tlgf`uHNC8nr^*5mjlGe#L2w|=c8HKoskPP ztwyVnh~#&v1Ox^kV*w}y%P046n04gG#a_}WxIa9uXwc))O(rQ&o4zL6Y9ErO%@ZXG zClz?}zaxA_lj@(qOXT;xK()TR+i>Q9Wk?D+AXF~&-3v>F?$Ui$(NirLX?SRZ`+T*y z%A)T$xyF-ZfhqiI9js+=3)a4Tgy#yZtFIpP$_$2EgW}T;iUWh>6|-Z!h@rUHdoQSt zo^g^48}kQTdPF(wMeV$38bJ{me`99SY^vn}OjTTl)vXA@O$6Reg!zMSb&m1@xl;J( zzc5i(cf$B~5QL5pu0&SrKVjZhub^jHO~2Lr>lyuC@ivxH5N3ZB#%~bItN)GXD3(vh zo9U5($Xqc+U_4X2ouJf5jaoT~652%l=ZQBX>Kx=_bEVjuWR2)2a;TPZTY_`SPTAd0 znKk7TxTQUsdIQOM)?-Z04Wat2^ewlhQgw*yEZ`2kb z8tw>?M9&_$@(@EhoQWX)c!lV#3zg1*!OsNhojO`t$}tCSjrAw!NtVL88g6ARX_N>V zA)9?ldPQZZhs4EchiQM~O%ktsANOd$Vxv*`>5gTr{Zv%s z{`t;7KY_+&_m`*a*DvYv$%l|iqI&CDyYOk*SQB@pv6)g`7#b*lFl^K{XJH8=!*N(r z`0F{O%galO7V7;nE#_!Fmon<=W{!`UGj@nk&E@{*MM;Sp5-1_gQP1Ib`#bplzG+h` z`thGA;c9P9=L__CBLL+AjJDg=m&XSXGl%`!uf;Mh&}f5N0TYcl2t-sR%U_@6EA&N^ zG`j3<0B?A;b}8c!0z(&ECj>}0;CI( zfWz8|>q|3uXrr^a;pe@c;QQbK)iAJgfsirq^S@)bI83fCZ@&&>T@!wJHg{HybGZHJ zXta^{okL>u2PP8at)!{PH~I<&0r5AV)Sx?tJGD|UUk=`R(EnTQAP_urk6 zjOaxVQsK<7mVlf2!HpLItPiy|cY_;ylM<0#Z;CWkNT5Bqm7x6NPh}8huq*PTVFKVf z2PPSXyC2?v)1CJufbePa!imH0p}T!>ImN_cfP)YYp?AnJ?>M|tMNL^d@YOllLeLkP zy{mERG>4yy9PgE3_H^y!`z^wp!By$B{{0j(QqnstgA%Xm=J^@I>UhpvW*-qkQz{^a z(W1;RFV&=$TOXv(-_Vw{I5K%9R2p_k8w$0Eiy8tG07L%GWdMN`s^eTdfxDlL7VQAZ zgp~k3phCw6f=*-;BTY%1PMm*imo>ZRaxSprz!zKs>$g8uh()6W8d>VansnHMs^*HB zOb5EE+vf0yVUgjlAhDFx3bJ@x8WCMGii(LcrXX0?`}**W&H_JQQ4#a2C>a^WeA=R_ zs-m{6@`c&oVj(&@x~>GaHZ~x$nE*NQJmAz?aN% zdSBNe1*akYTMv}nlY5R7Etm`mmXyxRw5E9=1QHIfqlA|f`6t8BkQy*l@)+ze>rsP< z9$QnRC7byD{&474hKhcY{j?F~8z`tw1w z$bfVvu5{lPJ}geu8C2oh2V;5I_Z>e^XFeKa)Hon3I6T8I^al=o%NwaSMS0dO>K2FL z9wcIZM`L?x*-87L=eaEEIijZROl#VH9)#L?p6k38N4BvpZP$UsrUNvhf1UJ10tjVb z-t!##{uWPAp)(PZQO{`n*C3x(8?7g;U{@LwC3=J1so+RrJzr=@Eui}8|F-Q3R z>|MLZHFvb{rcBTVeLZT879)p(HOo#d-5c3t0LfTpf^El^%^R_L^Xi{`Y!h~E3u!zE z-q%Rx`XM2Q)#^aMR~L3_V4NZ zvqSTo@o3t~8lh8qwOXsi2&fSX3RjVlu7Q%8axMk*`8h9gvf$KPlPfK zKfbY=z*4#yL@*>Q#$>MuTmm#}(-HE&C;B(2BK7Ho+;e zK%li_eW^z@0wHYRQU&qO$Q5oG_-UP71kBO8Q=P0&>X92XJ?xmhn`iKq6}h>TnbEd( zduW$`w@u*oE+HQ|@ZL>MJ{|?&PZkv9=id6XEjPQ9@_5AT+_gL|9S+-!S6D~=(;=Xb z8+hXWFp;N{rN`=52AFbIR$d@8+tVw`H$uw*SlkG#a);8 zooE8U$zPu`vP=@~-C!zi*zh|jO(DN**3fegoDakSJ&?4SX>)&irDbG$3KUYmAeGPx%l4 zl6@A1f(|IvNF|1lQ%EkiX+h^CMpIP_TEy25Eoasfn4^yPaS6Iy=x!CvOzH~5DGC!C1)HK z74N1f3N4ZfVLV8=0?4B!?d~a@ooJ03-%RhO0kk%D1Rj`U!K2V5`NxJ zvPJEV4Kish-M`0QPe?$YKot!X%)}hep9jxZ1vgglQLQ_kyJY7!i!AWz&m687?hkEM z!UH|4zCe$GB4^ckEQtXsL@-V78x@p)Qh|?v3=B=TBUsBu(|oe5_EZ0f?BiH7KQKwX znt*E#0#Bn{5Oydaly9of7Jgbl$92(Yp$I@mt|Ss1fzZadZOk3Cq?!bNKIf+R{#PUq3jCohRi z+WTi-ZpTYohCk{o);q~s+x9nl>SxRCEiBN(svgX7yu3%YZ5Qj2OiSGkmyD{lySln? znSZSMy@CSy9X>*tYSf%~$f7fIhq2lV{^&C5>Ip+ffUtgHAAv`J8Jm_iC;UppRQ=7E zn30i@jl5wHfC)eSfk6|x?D#5b!o7!-CP`o8iUX$Q<3Y|g=crP-{* zM@}bmjm9U(f`G5}tAUm6?b}m5O{ttCKXKUi|Jmsi`N`Samq!!xiBNoJH7Hkt7e!E+ zoHVT}Mz%9EF;&;pe7Qp#6TG-Y^E(G*Sn#oaQ4wa74VSL1t%91#Wv+i8A>lv$@}-%H zh3R<&$Q#^IIXr3_mN8-f@9e6G;mdZK3JRPMHN&D<>D`UO$tNTB0J7Lv)sXOv%r?qV zC0HOQ>zbN;3C6`QbMG(ww}5F84+Lc2F&SX7IWOH)&*Y28W%2S^%6}VSxkn3A$~5YU zvFPn{CA-hix}e_bcr>>DUd>jsd>r8aqD8g^ODMDG#haX-q{TyrCXT)pi>}8| z%y)#~eBna7rTo1OCv(4sW(vi(ydn0oSC&!HV8Y4sJvo|qwUYi8ij{f7GrbP>>Gzt1 zw~b~RBhY)>mN@-dp;VHeK47e{4raVPip6N7FVBiog+LTe$7|j|2z&{+$cE`_-ob({ zN&sC!@Fk^8ld(m3TvFOqpvU`P@ne$X8n{aJ25poO_&j2(iOIjJ&7KQzxp7G#Z`={H zI^`0N&b%m>KZ*+m>PRRLO&S#*We*{XD62+H!V8nC)hIsw6{bIWnUt942IV%-LP^1r z*F*yO9s+r~LJ9ThTTolTw&lF2LUj}2i};le*EuXFCM{Lc{V6w1X9A0bjYh6XpGbcj z#Sx`sf^#ViS`ugLrLnmBogkAS2V=xeXxLy_aB%RqZ}6=KN*`RjrDh*a+G(=(PET1I z^;TBK?~a>K(#v^Rh_=3lj7;jj)(_^|>&0(FiG=?2z~jNDR73mdg}w>&@ZM5UYV z+z*bq-(1p~oZsHwel&JSDlBfzq2QvX=H;CSsS5(GgCHUxt!y}A_~*}`HB<3mcXo%g zEhQ-qAFBVdx{@Bkt)3SRBYb0~l#*-Pl&{;Q(lilNr^YoOD4O+Z3ZDu3-OsT{7ufc1 z7sSN4Y2zoqHY3QQkg9(9A3~cJyoxV1wUom>%sAGK<&sG?YrnbaE4B1$4p9Epl1bzD zH{)Vul8{zFX=O+7q)}Z9$X!5Z!?&eHP(VN|;H$B*F%}l}sK=vY)>jzOA1Z~zEVLr< zAb;FbuGPoa7sMM<%YT!RmG$^EN`!{yj+`}d&fY02(C89cTx_kXI@$IF_Y36*d{%yM z@1H-)xS`^dm~U`!&OIM#l9(MG9UHY{{GK20Kn;+Tl+>QZ9v3$$mD_${Fn_ogN>QL@ z-GQgl(b24$_oNras{2!|q_~8ar>Cn`ZCTkdAhDuEUV)_9=+MZs(@TzB6qUjoEax3I z{0O9-(W{e>J)0Mu6y(0XPff1Nwyz3STrHggi+OI*qBOA{9vht|$P?zh2VYw9WK^dpL;8eiV569lMQ z?zPq|Q*{rw$(M$$)oKMFB1gW}%s22)PAx^Hj{Sl@fxd*wp!qFz8E=_eCEKID3f~aJJg1rgz=*YLg_$t zU7~P>GHP-4FGj?$Ns$d#(%qc`(hdkiH`3kGB_RwY-SDmVy!w3S{Bzbd7uW2I*=y~!@3roA z_Ydk8Ght-EWCS76+w13!!er-HEb3P|5ksQ)$sE%N#)g>{<4bk>kL-LO<|7z+OF*3b z=8|S`>Q>+Vgp4bOQJX{a{fnslK-v5fWO)(lBAmh;Sw3iH`li-Ry6`12gm{|k)eakq z3j{`1RQw~J3FkbO*{!t3q{~%b-rn8@Ud#2}5_Puq!Sr8COE0vw9nZQAFKs_64-803 ze&XWdD&gXi?qJHGrUs)Sr@y`|Y-nicppSm>WYozj(v%v20_$-F_JTrv;P4^{fI{b} zK%>0>@ZrPP4j-BF4&+ zwz~mN^u|xIV7}YE@*IlAJBL zwXX8MNYg}fg9PwN?0Z$n*QFeCSQaUZIscX0PK>7?ZvSWFaNp;EmOIz?zMa~xpHn)8 zI>rOlbdlVuDlT@>KCi3ER9@EupYuZiTi3i$g~-hnbmZ0C_(%9Ci-(>~M8r|;Vn0U~ z8~ec47nWsl-Wx9yYuQJVc^XX38Ot!0dNb#q7Z_fY5S(CZ zxd?z4?8;=WH`Kww_`O$YFdo8kk)HE_S5ImqbJ=L=>@o6}QnHBufZ1ce%3`DhsMq#} zV|@&}Kwu;4Tp~HFv$XjlTlMIP8-rAhN$=-m`&Y8gw_?F3kM#d(s6Kpmvj`Gh|4&O@ z+~$%ln~HYJnJC(Hz~f<#^*8LcX+lQyd3^Hjqd?(&3C}Q@(C$dT9~i1j$sLO$wdY6S zk|Zr#j^g-9kKFRUT#*@gTTgPwHj&;RAeI*O0%TM4P$o#o+1;kt*jO!&^}`ys#;lT( zlm2NWi%MEeeNoGu^S-ML&-LVjZaJ<%U2SbwhCOC6BMwrx#Gh?SIU`{-G!O^@D`99j zdd{tJ!mu5el2(;!FWbfZ<{w(=jyZ-i@_aH(dbY%EbNoZ=4!@q%5{@zV)ty^KN)p0@xpG{AR1IC-`rDRIn)MJh z;|KDj^`h?8XW_zNWem>MuE4quU7)ya9A*xlQrDZYEIX=cF0{|@Zm&oLulNKim>oMK zzc=hU0DRZ0TgN}I6MzrD7yI&6Q_Xe~FjfXg#Lv!j=eargAHzEBawfBMj zoiedm8RFQx(OK2(qb=*t|9f|f*!_AU8g-!v2O&zXKwrN1euhDeg&~}jUCA7f#6HLO z_#bMalz|A3NbF+iK9dk?7qZDD8LbK#PhwA^IZ+ZEWhQ=zpn2z8Q3xw|Ew^*?mF$YD znSUP5yB@q5v@j-{61>>8yRIdo(u6Xh+E^31In3WP`8iX>=z^FI-wFvYVP-{eW#@J1 zys*64Pbk##GDo0;8d3jgZ?&S9@1lhjZJ?QbcTuUK85_Ens6fiW9Dr~2N_R^)c(!ug z+H{@0gZV=2zc-+vwM5ajJwPLUC=|eJb~wiDV7e={V<3geI^Le8c(FIQQ6E0+P5I}? zEkVy{xX@ZWt7(G|dlY|amr=?FE{k?y)o6KOihA;@7BeVpaUNOz?fP@(qRm4Rv?aRz zbzZ}Z)#!{;S%=kf!?x=8bJTx+<863lW?j=_hnKu6BO^@b$Bj$Z=;)`hbjOHqBrlQD zylc@j1UjBbM%>+7X9LHqh4dME=vOjHxzS7aptTAf6#?4#kviryT*z@i zQCL`dyq15J^L?mLX5+RHYnn7oqr+>({-^JJb~^v|f)3tzWQCoRjl1bipIWq9{!m)h zkQkJaa_d%x!E4a~W_O2RO^G9ZI=>Mg7Bs{dJNH|!!xOO@5)pB;)CLa-!>RQ+$M)R4 zkxR}z7z}W}e^+uD0lS!MLk*aIH_&J_9qI~SUT;4u#2?hU|7TF{Z_D-KzL!>=VPwh4 zf$)Z?M)RS;Z{N6Qwig#%uCHp5zlPGU`wV`Jaj zuWxp@3t0wz8M-pf4{=Q-34fKi+dX{Z$?GgR`We3RcW%`7QOj;EgXyBqo1>;av~%-w zB>DN%ssl+p3_PrNy7p)4>Oi_Cou3JBGr|BKpYC{(?z~VQNvZ67)N*m^b*9_42=*Ax0mkC#Y2@&AtPjXNo2 zxVPY0>F6jF!2*B^l6ZW{R}WnZanzr~vLs7~`l0$78lm{uSXj|+uDr=g@Z_+j-Y4Ye z_ZIItXB5;~CntAR+0L7}v&Jd-Md@)>)AaWZ9I~xtl!ug$9WIAocJpqdK ze;XLG4S=Z$@Ez7jmXcukgQ3o#)UYRFVw_MY2rz57^6|yMQ;S|(TT>1nfQ05&RQx+6 z8-qI8rZ0oNv-2l+x}A(&)e7fZP4qtJ(0mF`on%o45wu55 zf1mi->9@4pAj7FIJsO#E@;g5q3*)f;@B`aiZDztY`F^#tF#1Q}36h2H?66(fg7`$e zH}hr#skc+(n>_ni3*ufORhqu~s>)^BU(dd*0z`pM7L|~&6k4Yb?<}n6|j#(}2zQFBw~McCreVf4&!rR8EHAliKu&@sNfU@|m5VW5f~7*F`z%6j~@|h=~0I zjqzfEf#5#AUwPlOwu=+J8r(Kz1rjgYuU?v)n_ER&BG<$4BIEjs2h+t~F_b>S#m*2h zhWPTl{}h~9jb}jHLWXOQEMXhcwFVAzy^`_bQ#}bmXFLoHI+z@z)AnQAUr*uM@S8aR z8WG8-+gv@D0A% zAz?U$7GBT7+z!84R8`FsxdEdc{u%@Z^SxY>+vm2@6@oDs)aP9^-hNVFTo|x0`YhYn zDvqXG4T*I)^25d5;O!k<*IWN_Et;P$c)C~FUb?N(X#RA`gloKe_pY>|-03o6#~tK9 z)!Pl7P|Z%3ykUTZ+T0l#84+!oZu+nmQmB#tZte)Hay+55nnSy;-7EdZN6JUy`r}y1 ze0|11_vazH3b*4TG52PJMmJ(xkL7It`sT$-5DSPJz1ct6zP>qpdV9Hz92yq?4mj2C zX}HAU{z(~)$IjC&=beRkUWpE`D8gMq3)offz=ho-BFa9tr=`?Fx?(mh!&`r49v2g_ zGhC9uHf4Eb=hLW#h73i*`~0LpkEJ_qauMH>*_|lr4f#68QpDDq!_toJ-&lC3=z!hK zD0|vQIR3nCh^a#&ktnnGs@0~dT}cUmr=oUN*48vWvfutZw{d;7)`2sfTOHci;PJ(? zxmbe~cTR#^D`x~`HeZ~bjd(@LZBHS_HtXsdJUnc)>Ff+7kkbHqss>7(D)wILNLA3b zZ#)$-y_drlzC;%R(hP+t802a;Hx_ESd>3 zyDl#!7T(l-3`QdP$u$pHC1G4gCl)UHg=_@Mw4-8-uYi)^UQ|ew9s7BfJrnt3S$bt>4N0 zareqU)2q&cshefJU%$zymXnr_XSwloQBg_3X77cmd1l|Bc>eB2QXJHBzIe+*`^!es z#;f96i+@tekwa^%tL0k#9ib%od0gKj%Sb3FE>U%ku;|~jcFpsZ4lJJJS!rpM=_TwY zdYJKkmBE>$b^@sm4h{scn>#mljn`&I>e;ZYZjn^S{hv&f%Y`@^i*A?7my~nq2Zy9* z@c77Tz4P^Ft?{YH$?ul}pg=kGOmluQGG7Iw z?VI-!zGrnwWo|M#oxHmKo7VOB4HwM$&*{tR>&joD~BHw1{cdQ z%3$uhK=JS_6&*BW>#^I&NX4J=5Wxy`OBd@r1Jw%wU(+eOs*Q7Xh>am6fJwY*a9Oo5 zyM3DrlaFD9b$^~Lo}jAmuCMyAc7QdahMA>XjcwpzIWXsnqwisBF+sS;0B=;-k6r6Y(Zq^n0bn(bfM5QXGN8Yx}q|Lo|;D-*P8$`076` zEi(D0m7)IBFDf)ubg?x{MSs3f?a)O}AXV95pQN^SQYAwKga@)PF_mcDq`la9p{BpT znKy7GtOOUymx?W>2VIYE|psX5QLxu(1JS-!g&WNh^cLQZ(Fyf>%o^x7v*>cCPy^ zk2+Z(V%5loqin~#VsL9(RRKNJW^WHsUS7WEyjS%GLQKpazjOD_qW0(*zmh&D{2Fc` z;lBQrGk`Xzs7Qg?7wldWiswK?BiWlrPC9Ap>t{_^xl%qtjN{N99qnc4SEBIHeQ(B; zGxeK1k_D`#@Y^f5CP{J80P+9-2AgOJw&b`L@V?pz5W&Q1m6ph{9`1pgnpFZbEDVru588c7KyuK#ST9Kl< z{|GZHQ&Dk?!Y$OO?%3^TqHPwDfq?{NS1sir&QR$>m1F46+RBPQ{=v}(GS_|;4;m9` zhX;;b)$vnCy->INunI>xA4d6h5+N7)#_g`0Z2GZLNZGVar3_GcjU^@w1}7*1 z8W<%ZY$C3D&vh)0ja~6z zRPjI&6VhsPv#(xHnnghWN}Fh;-`kRw$x}uwgg(4q%t#jX8S3I~=zO@U-XwNX<)ZH;NB}cz9(w#ts@eBNnvs<#}}>ZEI&B0u%|uAn@(srBIg1 z$*L_>qqldocXV)YeEmeHzD|UnoIk=)$e}=@=Urn{Q%S_kK>m+{tu2fKCGB!XG1`_) z+8{6wAT<PO|_MIVHDNLa2P5nZA!{&6*$W+oCTAFpe#vo&%*fnsoW^6Yax!k)ozP2uv zk(MUM4FK4lz%oNZa$12^kJHrDbdZvw`=I*n)paI(`TT}h{{(o8+1S|9(E>fl$c`;qsVC- zWiwS&=jTO=JB%b?Wk~~dC0w!79w5&f(ZI(2WOZNL!3PFYVqO{8s?}s~+?9dg2jN@2 zX7vZwR7PMI9d+LFyfU$YfTT7)023l2@)9#E;6evImVl6aotE%NPjO+%4ru_^{YMr2 zJGuR-qSik+aN96_ejgqWxSVL~w8XK-f^f@-6&Kq#^9zlaT>1?km%l$?JKN09%zm)Q zT3IJmI*HWcAW1YlNw@q*$0~HLVw3N(Iid8-m-8Tk+GQ$Ig7)gUFT$-DFFv}g%&!a? z!Zu>G{k6O@A>Z}eCa2$v&T`W`pFa8f`&;Yl*E{X7?_IB417Wyl?StD~&>9I*!{uN- z@M@GK^sy)fB})ve1)RLoYknt?nv;`501FNdW|W7_v3i-mn>5pK&%f(D;(V3VI$ydRf$QLGXkW={s_*@OflE*Hf1+@dSBJq zwtWd;Ktk#33v4w3i+){W2zolsH^eEY+fRa-mYz1BtB*T_D9V_%y85L;8prmI2eqBOTS{y! z*fvmi=1>vC-%G7DMa64E5vmziQ(gH7;xco>huMi zDi!pfK^V3VEmTa*d;oR$*qHfwet)WUeM1fg^~nle04^lDmEKzBv!k-mF}-?&t=LLg zn!x(3Yky+NOnyr@qoD3LeuiQ3n@_)wkNL^NSya=kthYSnvV1?Q4yRk#So}kZOCIiY zI`{@y(QzOgq$GqeyzzVI!#(fp++>5(<+-t!m}N9kJMme#)FUrHjlZCCevlx2*K zr7|DB(?R4_R!(c6n21g)S_v`lXDl=!5Cb}hP6&wH`AJCVm_C!K=!UJe?dsxoaCSAv zo>=8oHhm)EbcQd9-^2^|i_+SbBfS5LL&o-HJGb7*58&Ge5a~{q2ne5fRHq?kmburh zI~<-|g>)Edx@X|E4@#N)KcjUy=wYgw_fQqPe);@4h&b@~m#%k$t3Lc8_)nUUYwzdD zP`~esVwG_c-4`JO{yiqoG5rI<*6;@qHO%d$I>#8YvSplkx~0utJ9QmK`=^NrgXRbj z35^2)gqz*nPd6)%#yS)ga@C)F)H?2pKZIM7@JpC3Y}s8M$G`q@b>49+8$LI35ASjx zgLzqN((f^=xJe8}Jc`~|8c2kuQrq6H>|hO;9x{TzoJk^zBjt2e@ZSY=nCtBJ&|HRST;(CND@uV&4W7t(p?2zjPiX+B4QG7*2l%U-fg0lc-mZC9GlWR(5R`a zyG66q+|4!Hz4l=Y!bybX|KR)qw)Bv`bWYC`!eAK8$JS8wc6SpvjAxk!D$76dz36e! z++^4eQM7T!3t2W<83BA=KR6FR>{B zVDp#_kM%!dw#^?(^yV%))Gu9z%Fn7*utX` zo|&Eo7Ng_uhsA|TV{^60X`3pAiKg2Y$xC-UYG_=d!Lt~Xw=b4@LHtI(4T^&N9WjL9 zK3(j&?afgvFdcXvwMwL?r_Wx#`!&~eO=0D(1CqwfQw1|bT(^+}6o60eqEO{{eSLir zA2+_Kl_Tqr#PZRVssKuk_U7VwK4^uikj(<3YE(XvV#FRzcAK0#@-KVYHVG z@qh&+ul``^URY9`x2t|PZ-mq;)+}{fgX?QIx=sAYR_G${=Bh0$wp)@0wJ*;qWQEdS z?RVvm{o2;6cTz_DkZb(%M&ymY*C*RF+Mu0T=Z_yNB(Cf8C9XEwCW>D-o{ff52zn7d zrqIyQblMoE(=`Ed32qx-g6WIQpKX!iX%Z6B!Y-vHz@+S7Hze~NIAUNMy~$KXKT_68 z-x=JXP8?~{;kTmamy12kP$~7NsDtah)h%(6%(`tVwgsosaG0_ltH5;RUv_|oXBW_C zReAG~t5{Q?ikeK!cAYXfv@brBD=vX(WCh>K&TdHD@w<(Hatf4lv#d}iXZdKq|Kwz0 zAS^>)pDt?!K!KvHF*e|gP9L2Tyxjn8qAM_y8EFwL${aSsBRfhVWK@tD$pj=r_B)FXu5^C(mhcep{yHc ziKir_jTYJ`fOR#^{=VS7JmxnDiyg3;Ej?lW zkgUZ+G*bL5$lk%>ayHdYt3RQ7!L93upEc1Ju};q|;jC*+&K~}+t3sJ;iY!x+4VSjR zmiy2z3H~l(Z{Ce{=HK`!{MG@_=_N5ME2@Tnd4(pWDg?}!Jz0L{X03%ok_!UCfIb&) z22|aTXXVRsi#Fpv+H@71fl`=QQNyFUvRo9jjSv2G`IZ}3&{_3DO9B@?R{XxqYhXlx z-&~JuPdl7>=$o5Q?ys=0v9WJTHjBBj>yN9r;Q)699HZG!ONGJ#AmeT1te%r(M21Ex zCTGSZB@K_xRM~C`q^ro{)eU(yn1*1RoY(N$F!b1q6S8t#6un&Xi}u#@nK1xMeM?ZU9xO9vwdR)RYwBAl~W3`aCaP_41b?% z7~^R9t}!7QN48r(pFqM};urIWFWeoHxjlIk#Q`u&L4%GzevHt*g*Im@4HwzX&3wUb z>A!9nh~z^O(%5fK44eI}Q> z(N>^)U6c5T@?ZZQ8rsDta^N1bXyJ+DNzD{UW_Q?|uMqm2qPexK7?5sWj};^Sm!4?2 zn7n#u-fF~DElQ+ASf|Dpu1o4zz8&rTkaBrbge{$d73ZXvz(P^g@ZP`sC*VFA*WbCK zp>bD@%>Mk}OK|-x0Ox Date: Sat, 28 Dec 2024 12:38:44 +0000 Subject: [PATCH 167/168] Remove CosmicItemRenderer Class Removed CosmicItemRenderer Class. This has been Replaced By CosmicHaloItemRender from Avaritia. Update Avaritia Dependencies --- dependencies.gradle | 4 +- .../items/materialitem/MetaPrefixItem.java | 5 +- .../gregtech/api/items/metaitem/MetaItem.java | 7 +- .../renderer/item/CosmicItemRenderer.java | 188 ------------------ 4 files changed, 9 insertions(+), 195 deletions(-) delete mode 100644 src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java diff --git a/dependencies.gradle b/dependencies.gradle index 17ab5a973d1..d6c8b9c2f95 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -51,7 +51,7 @@ dependencies { compileOnly("curse.maven:journeymap-32274:5172461") // Journeymap 5.7.1p3 compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 compileOnly("curse.maven:xaeros-263420:5394758") // Xaero's Minimap 24.2.0 - compileOnly rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 + compileOnly rfg.deobf("curse.maven:avaritia-1-1x-unofficial-1165010:6029951") // Avaritia 3.3.0.39 compileOnly rfg.deobf("curse.maven:opencomputers-223008:5274236") // OpenComputers 1.8.5+179e1c3 compileOnly rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 compileOnly rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 @@ -62,7 +62,7 @@ dependencies { // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - // runtimeOnlyNonPublishable rfg.deobf("curse.maven:avaritia-261348:3143349") // Avaritia 3.3.0.37 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:avaritia-1-1x-unofficial-1165010:6029951") // Avaritia 3.3.0.39 // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 diff --git a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java index a2fe30037be..a1c3066afa2 100644 --- a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java +++ b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java @@ -17,9 +17,10 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.Mods; -import gregtech.client.renderer.item.CosmicItemRenderer; import gregtech.common.creativetab.GTCreativeTabs; +import morph.avaritia.client.render.item.CosmicHaloItemRender; + import net.minecraft.block.BlockCauldron; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.block.model.IBakedModel; @@ -153,7 +154,7 @@ public void registerModels() { if (Avaritia.isModLoaded()) { ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); - IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, + IBakedModel wrapped = new CosmicHaloItemRender(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); ModelRegistryHelper.register(location, wrapped); diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index bc10af80e74..b562b482e58 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -31,12 +31,13 @@ import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; import gregtech.api.util.Mods; -import gregtech.client.renderer.item.CosmicItemRenderer; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.common.ConfigHolder; import gregtech.common.covers.filter.IFilter; import gregtech.common.creativetab.GTCreativeTabs; +import morph.avaritia.client.render.item.CosmicHaloItemRender; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ModelBakery; @@ -190,7 +191,7 @@ public void registerModels() { if (Avaritia.isModLoaded()) { ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); - IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, + IBakedModel wrapped = new CosmicHaloItemRender(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); ModelRegistryHelper.register(location, wrapped); } @@ -206,7 +207,7 @@ public void registerModels() { new ModelResourceLocation(resourceLocation, "inventory")); if (Avaritia.isModLoaded()) { ModelResourceLocation location = new ModelResourceLocation(resourceLocation, "inventory"); - IBakedModel wrapped = new CosmicItemRenderer(TransformUtils.DEFAULT_ITEM, + IBakedModel wrapped = new CosmicHaloItemRender(TransformUtils.DEFAULT_ITEM, (modelRegistry) -> modelRegistry.getObject(location)); ModelRegistryHelper.register(location, wrapped); } diff --git a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java b/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java deleted file mode 100644 index d021a7bbd9a..00000000000 --- a/src/main/java/gregtech/client/renderer/item/CosmicItemRenderer.java +++ /dev/null @@ -1,188 +0,0 @@ -package gregtech.client.renderer.item; - -import gregtech.api.util.Mods; - -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import net.minecraftforge.common.model.IModelState; -import net.minecraftforge.fml.common.Optional; - -import codechicken.lib.colour.Colour; -import codechicken.lib.model.ItemQuadBakery; -import codechicken.lib.model.bakedmodels.ModelProperties; -import codechicken.lib.model.bakedmodels.PerspectiveAwareBakedModel; -import codechicken.lib.util.TransformUtils; -import com.google.common.collect.ImmutableList; -import morph.avaritia.api.ICosmicRenderItem; -import morph.avaritia.api.IHaloRenderItem; -import morph.avaritia.client.render.item.WrappedItemRenderer; -import morph.avaritia.client.render.shader.CosmicShaderHelper; - -import java.util.HashMap; -import java.util.List; -import java.util.Random; - -@Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.ICosmicRenderItem") -@Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.api.IHaloRenderItem") -@Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.client.render.item.WrappedItemRenderer") -@Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.client.render.shader.CosmicShaderHelper") -public class CosmicItemRenderer extends WrappedItemRenderer { - - private static final HashMap spriteQuadCache = new HashMap(); - - private Random random = new Random(); - - // Had to use Avaritia's render and modify it to allow for Cosmic Render With Halo and Pulse Effect - // I Didn't create these methods here, these are Avaritia's (Some of which have been cleaned/modified) - // Available here -> https://github.com/Morpheus1101/Avaritia - - public CosmicItemRenderer(IModelState state, IBakedModel model) { - super(state, model); - } - - public CosmicItemRenderer(IModelState state, WrappedItemRenderer.IWrappedModelGetter getter) { - super(state, getter); - } - - public void renderItem(ItemStack stack, ItemCameraTransforms.TransformType transformType) { - Tessellator tess = Tessellator.getInstance(); - BufferBuilder buffer = tess.getBuffer(); - if (stack.getItem() instanceof IHaloRenderItem && transformType == ItemCameraTransforms.TransformType.GUI) { - IHaloRenderItem hri = (IHaloRenderItem) stack.getItem(); - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.disableDepth(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - GlStateManager.disableAlpha(); - if (hri.shouldDrawHalo(stack)) { - Colour.glColourARGB(hri.getHaloColour(stack)); - TextureAtlasSprite sprite = hri.getHaloTexture(stack); - double spread = (double) hri.getHaloSize(stack) / 16.0; - double min = 0.0 - spread; - double max = 1.0 + spread; - float minU = sprite.getMinU(); - float maxU = sprite.getMaxU(); - float minV = sprite.getMinV(); - float maxV = sprite.getMaxV(); - buffer.begin(7, DefaultVertexFormats.POSITION_TEX); - buffer.pos(max, max, 0.0).tex((double) maxU, (double) minV).endVertex(); - buffer.pos(min, max, 0.0).tex((double) minU, (double) minV).endVertex(); - buffer.pos(min, min, 0.0).tex((double) minU, (double) maxV).endVertex(); - buffer.pos(max, min, 0.0).tex((double) maxU, (double) maxV).endVertex(); - tess.draw(); - } - - if (hri.shouldDrawPulse(stack)) { - GlStateManager.pushMatrix(); - double scale = this.random.nextDouble() * 0.15 + 0.95; - double trans = (1.0 - scale) / 2.0; - GlStateManager.translate(trans, trans, 0.0); - GlStateManager.scale(scale, scale, 1.0001); - renderModel(this.wrapped, stack, 0.6F); - GlStateManager.popMatrix(); - } - - renderModel(this.wrapped, stack); - GlStateManager.enableAlpha(); - GlStateManager.enableDepth(); - GlStateManager.enableRescaleNormal(); - GlStateManager.disableBlend(); - GlStateManager.popMatrix(); - } else { - renderModel(this.wrapped, stack); - - } - if (transformType == ItemCameraTransforms.TransformType.GUI) { - this.renderInventory(stack, this.renderEntity); - } else { - this.renderSimple(stack, this.renderEntity); - } - } - - protected void renderSimple(ItemStack stack, EntityLivingBase player) { - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - World world = player != null ? player.world : null; - IBakedModel model = this.wrapped.getOverrides().handleItemState(this.wrapped, stack, world, player); - renderModel(model, stack); - if (stack.getItem() instanceof ICosmicRenderItem) { - ICosmicRenderItem cri = (ICosmicRenderItem) stack.getItem(); - GlStateManager.disableAlpha(); - GlStateManager.depthFunc(514); - TextureAtlasSprite cosmicSprite = cri.getMaskTexture(stack, player); - IBakedModel cosmicModel = (IBakedModel) spriteQuadCache.computeIfAbsent(cosmicSprite, - CosmicItemRenderer::computeModel); - CosmicShaderHelper.cosmicOpacity = cri.getMaskOpacity(stack, player); - CosmicShaderHelper.useShader(); - renderModel(cosmicModel, stack); - CosmicShaderHelper.releaseShader(); - GlStateManager.depthFunc(515); - GlStateManager.enableAlpha(); - } - - GlStateManager.disableBlend(); - GlStateManager.popMatrix(); - } - - private static IBakedModel computeModel(TextureAtlasSprite sprite) { - List quads = ItemQuadBakery.bakeItem(ImmutableList.of(sprite)); - return new PerspectiveAwareBakedModel(quads, TransformUtils.DEFAULT_ITEM, new ModelProperties(true, false)); - } - - protected void renderInventory(ItemStack stack, EntityLivingBase player) { - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - GlStateManager.disableAlpha(); - GlStateManager.disableDepth(); - World world = player != null ? player.world : null; - IBakedModel model = this.wrapped.getOverrides().handleItemState(this.wrapped, stack, world, player); - renderModel(model, stack); - if (stack.getItem() instanceof ICosmicRenderItem) { - ICosmicRenderItem cri = (ICosmicRenderItem) stack.getItem(); - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - GlStateManager.disableAlpha(); - GlStateManager.disableDepth(); - TextureAtlasSprite sprite = cri.getMaskTexture(stack, player); - IBakedModel cosmicModel = (IBakedModel) spriteQuadCache.computeIfAbsent(sprite, - CosmicItemRenderer::computeModel); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - CosmicShaderHelper.cosmicOpacity = cri.getMaskOpacity(stack, player); - CosmicShaderHelper.inventoryRender = true; - CosmicShaderHelper.useShader(); - renderModel(cosmicModel, stack); - CosmicShaderHelper.releaseShader(); - CosmicShaderHelper.inventoryRender = false; - GlStateManager.popMatrix(); - } - - GlStateManager.enableAlpha(); - GlStateManager.enableRescaleNormal(); - GlStateManager.enableDepth(); - GlStateManager.disableBlend(); - GlStateManager.popMatrix(); - } -} From 1a6340da171013c33e9c93c1f0bb9349bf78b984 Mon Sep 17 00:00:00 2001 From: jude123412 <104434396+jude123412@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:12:02 +0000 Subject: [PATCH 168/168] Remove Avaritia Textures Import --- src/main/java/gregtech/api/items/metaitem/MetaItem.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index b562b482e58..f94210f42ac 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -93,7 +93,6 @@ import morph.avaritia.api.ICosmicRenderItem; import morph.avaritia.api.IHaloRenderItem; import morph.avaritia.api.registration.IModelRegister; -import morph.avaritia.init.AvaritiaTextures; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -139,9 +138,6 @@ @Optional.Interface( modid = Mods.Names.AVARITIA, iface = "morph.avaritia.api.registration.IModelRegister") -@Optional.Interface( - modid = Mods.Names.AVARITIA, - iface = "morph.avaritia.init.AvaritiaTextures") public abstract class MetaItem.MetaValueItem> extends Item implements ItemUIFactory, IOverlayRenderAware, IHaloRenderItem, ICosmicRenderItem, IModelRegister { @@ -820,7 +816,7 @@ public boolean shouldDrawHalo(ItemStack stack) { public TextureAtlasSprite getHaloTexture(ItemStack stack) { T metaValueItem = getItem(stack); if (metaValueItem.registerHaloTexture(stack) == null) { - return AvaritiaTextures.HALO; + return MetaValueItem.CosmicTexture.specialMaskTextures.get("fallback"); } return MetaValueItem.CosmicTexture.haloTextures.get(metaValueItem.registerHaloTexture(stack)); } @@ -859,7 +855,7 @@ public boolean shouldDrawPulse(ItemStack stack) { public TextureAtlasSprite getMaskTexture(ItemStack stack, EntityLivingBase player) { T metaValueItem = getItem(stack); if (metaValueItem.registerMaskTexture(stack) == null) { - return AvaritiaTextures.INFINITY_SWORD_MASK; + return MetaValueItem.CosmicTexture.specialMaskTextures.get("fallback"); } return MetaValueItem.CosmicTexture.maskTextures.get(metaValueItem.registerMaskTexture(stack)); }