diff --git a/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java b/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java index 850d3f6ad..0186bab53 100644 --- a/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java +++ b/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java @@ -299,6 +299,10 @@ public class SuSyRecipeMaps { .setProgressBar(GuiTextures.PROGRESS_BAR_SIFT, ProgressWidget.MoveType.VERTICAL) .setSound(GTSoundEvents.BATH); + public static final RecipeMap PUMPING_RECIPES = new RecipeMap<>("large_fluid_pump", 1, 0, 0, 1, new BiomeRecipeBuilder(), false) + .setProgressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR, ProgressWidget.MoveType.HORIZONTAL) + .setSound(GTSoundEvents.MINER); + public static final RecipeMap DRONE_PAD = new RecipeMap<>("drone_pad", 4, 9, 0, 0, new DronePadRecipeBuilder(), false); public static final RecipeMap BLENDER_RECIPES = new RecipeMap<>("blender", 9, 1, 6, 2, new SimpleRecipeBuilder().EUt(VA[LV]), false) diff --git a/src/main/java/supersymmetry/api/recipes/builders/BiomeRecipeBuilder.java b/src/main/java/supersymmetry/api/recipes/builders/BiomeRecipeBuilder.java new file mode 100644 index 000000000..c30b96f97 --- /dev/null +++ b/src/main/java/supersymmetry/api/recipes/builders/BiomeRecipeBuilder.java @@ -0,0 +1,96 @@ +package supersymmetry.api.recipes.builders; + +import gregtech.api.recipes.Recipe; +import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.recipes.RecipeMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.biome.Biome; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.jetbrains.annotations.NotNull; +import supersymmetry.api.recipes.properties.BiomeProperty; + +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * A custom recipeBuilder, for allowing us to put our own recipeProperty {@link BiomeProperty} into a recipe + */ +public class BiomeRecipeBuilder extends RecipeBuilder { + + public BiomeRecipeBuilder() { + } + + public BiomeRecipeBuilder(Recipe recipe, RecipeMap recipeMap) { + super(recipe, recipeMap); + } + + public BiomeRecipeBuilder(RecipeBuilder recipeBuilder) { + super(recipeBuilder); + } + + @Override + public BiomeRecipeBuilder copy() { + return new BiomeRecipeBuilder(this); + } + + @Override + public boolean applyProperty(@NotNull String key, Object value) { + if (key.equals(BiomeProperty.KEY)) { + if (value instanceof BiomeProperty.BiomePropertyList list) { + BiomeProperty.BiomePropertyList biomes = getBiomePropertyList(); + if (biomes == BiomeProperty.BiomePropertyList.EMPTY_LIST) { + biomes = new BiomeProperty.BiomePropertyList(); + this.applyProperty(BiomeProperty.getInstance(), biomes); + } + biomes.merge(list); + return true; + } + return false; + } + return super.applyProperty(key, value); + } + + public BiomeRecipeBuilder biomes(String... biomes) { + return biomes(false, biomes); + } + + private BiomeRecipeBuilder biomes(boolean toBlacklist, String... biomeRLs) { + List biomes = new ArrayList<>(); + for (String biomeRL : biomeRLs) { + Biome biome = Biome.REGISTRY.getObject(new ResourceLocation(biomeRL)); + if (biome != null) { + biomes.add(biome); + } else { + throw new NoSuchElementException("No biome with ResouceLocation \"" + biomeRL + "\" found"); + } + } + return biomesInternal(toBlacklist, biomes); + } + + private BiomeRecipeBuilder biomesInternal(boolean toBlacklist, List biomes) { + BiomeProperty.BiomePropertyList biomePropertyList = getBiomePropertyList(); + if (biomePropertyList == BiomeProperty.BiomePropertyList.EMPTY_LIST) { + biomePropertyList = new BiomeProperty.BiomePropertyList(); + this.applyProperty(BiomeProperty.getInstance(), biomePropertyList); + } + for (Biome biome : biomes) { + biomePropertyList.add(biome, toBlacklist); + } + return this; + } + + public BiomeProperty.BiomePropertyList getBiomePropertyList() { + return this.recipePropertyStorage == null ? BiomeProperty.BiomePropertyList.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(BiomeProperty.getInstance(), + BiomeProperty.BiomePropertyList.EMPTY_LIST); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .appendSuper(super.toString()) + .append("biomes", getBiomePropertyList()) + .toString(); + } +} diff --git a/src/main/java/supersymmetry/api/recipes/properties/BiomeProperty.java b/src/main/java/supersymmetry/api/recipes/properties/BiomeProperty.java new file mode 100644 index 000000000..ea3895893 --- /dev/null +++ b/src/main/java/supersymmetry/api/recipes/properties/BiomeProperty.java @@ -0,0 +1,87 @@ +package supersymmetry.api.recipes.properties; + +import gregtech.api.recipes.recipeproperties.RecipeProperty; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class BiomeProperty extends RecipeProperty { + + public static final String KEY = "biome"; + + private static BiomeProperty INSTANCE; + + private BiomeProperty() { + super(KEY, BiomePropertyList.class); + } + + public static BiomeProperty getInstance() { + if (INSTANCE == null) + INSTANCE = new BiomeProperty(); + return INSTANCE; + } + + private static String getBiomesForRecipe(List value) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < value.size(); i++) { + builder.append(value.get(i).biomeName); + if (i != value.size() - 1) + builder.append(", "); + } + String str = builder.toString(); + + if (str.length() >= 13) { + str = str.substring(0, 10) + ".."; + } + return str; + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + BiomePropertyList list = castValue(value); + + if (list.whiteListBiomes.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("susy.recipe.biomes", + getBiomesForRecipe(castValue(value).whiteListBiomes)), x, y, color); + if (list.blackListBiomes.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("susy.recipe.biomes_blocked", + getBiomesForRecipe(castValue(value).blackListBiomes)), x, y, color); + } + + public static class BiomePropertyList { + + public static BiomePropertyList EMPTY_LIST = new BiomePropertyList(); + + public final List whiteListBiomes = new ObjectArrayList<>(); + public final List blackListBiomes = new ObjectArrayList<>(); + + public void add(Biome biome, boolean toBlacklist) { + if (toBlacklist) { + blackListBiomes.add(biome); + whiteListBiomes.remove(biome); + } else { + whiteListBiomes.add(biome); + blackListBiomes.remove(biome); + } + } + + public void merge(@NotNull BiomeProperty.BiomePropertyList list) { + this.whiteListBiomes.addAll(list.whiteListBiomes); + this.blackListBiomes.addAll(list.blackListBiomes); + } + + public boolean checkBiome(Biome biome) { + boolean valid = true; + if (this.blackListBiomes.size() > 0) valid = !this.blackListBiomes.contains(biome); + if (this.whiteListBiomes.size() > 0) valid = this.whiteListBiomes.contains(biome); + return valid; + } + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java b/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java index acf52af72..7a6026a60 100644 --- a/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java +++ b/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java @@ -134,6 +134,7 @@ public class SuSyMetaTileEntities { public static MetaTileEntityFrothFlotationTank FROTH_FLOTATION_TANK; public static MetaTileEntityMultiStageFlashDistiller MULTI_STAGE_FLASH_DISTILLER; + public static MetaTileEntityLargeFluidPump LARGE_FLUID_PUMP; public static MetaTileEntityOceanPumper OCEAN_PUMPER; public static MetaTileEntityHighTemperatureDistillationTower HIGH_TEMPERATURE_DISTILLATION_TOWER; public static MetaTileEntityRotaryKiln ROTARY_KILN; @@ -273,6 +274,8 @@ public static void init() { PHASE_SEPARATOR[0] = registerMetaTileEntity(17018, new MetaTileEntityPhaseSeparator(susyId("phase_separator"))); BATH_CONDENSER[0] = registerMetaTileEntity(17019, new MetaTileEntityBathCondenser(susyId("bath_condenser"))); + LARGE_FLUID_PUMP = registerMetaTileEntity(17021, new MetaTileEntityLargeFluidPump(susyId("large_fluid_pump"))); + registerSimpleMTE(ELECTROSTATIC_SEPARATOR, 12, 17035, "electrostatic_separator", SuSyRecipeMaps.ELECTROSTATIC_SEPARATOR, SusyTextures.ELECTROSTATIC_SEPARATOR_OVERLAY, true, GTUtility.defaultTankSizeFunction); registerSimpleMTE(POLISHING_MACHINE, 12, 17048, "polishing_machine", SuSyRecipeMaps.POLISHING_MACHINE, SusyTextures.POLISHING_MACHINE_OVERLAY, true, GTUtility.defaultTankSizeFunction); registerSimpleMTE(TEXTILE_SPINNER, 12, 17061, "textile_spinner", SuSyRecipeMaps.SPINNING_RECIPES, SusyTextures.TEXTILE_SPINNER_OVERLAY, true); diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/MetaTileEntityLargeFluidPump.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/MetaTileEntityLargeFluidPump.java new file mode 100644 index 000000000..d791afdb3 --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/MetaTileEntityLargeFluidPump.java @@ -0,0 +1,200 @@ +package supersymmetry.common.metatileentities.multi.electric; + +import gregtech.api.capability.impl.MultiblockRecipeLogic; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.recipes.Recipe; +import gregtech.api.unification.material.Materials; +import gregtech.api.util.RelativeDirection; +import gregtech.client.renderer.ICubeRenderer; +import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.TooltipHelper; +import gregtech.common.blocks.BlockBoilerCasing.BoilerCasingType; +import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; +import gregtech.common.blocks.BlockTurbineCasing.TurbineCasingType; +import gregtech.common.blocks.MetaBlocks; +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; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; +import supersymmetry.api.recipes.SuSyRecipeMaps; +import supersymmetry.api.recipes.properties.BiomeProperty; +import supersymmetry.client.renderer.textures.SusyTextures; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +import static gregtech.api.util.RelativeDirection.FRONT; +import static gregtech.api.util.RelativeDirection.RIGHT; + +public class MetaTileEntityLargeFluidPump extends RecipeMapMultiblockController { + + public MetaTileEntityLargeFluidPump(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, SuSyRecipeMaps.PUMPING_RECIPES); + this.recipeMapWorkable = new LargePumpRecipeLogic(this); + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityLargeFluidPump(this.metaTileEntityId); + } + + @Override + public boolean isMultiblockPartWeatherResistant(@Nonnull IMultiblockPart part) { + return true; + } + + @Override + public boolean getIsWeatherOrTerrainResistant() { + return true; + } + + @Override + public boolean allowsExtendedFacing() { + return false; + } + + @NotNull + @Override + protected BlockPattern createStructurePattern() { + return FactoryBlockPattern.start(RIGHT, FRONT, RelativeDirection.UP) + .aisle(" ", " P", " ") + .aisle(" ", " P", " ") + .aisle("FCCCC ", "CCCCC P", "FCECC ") + .aisle("CCSGC ", "OPPPPPP", "CCECC ") + .aisle("FCCC ", "CCCCC ", "FCEC ") + .where(' ', any()) + .where('S', selfPredicate()) + .where('P', states(getPipeCasingState())) + .where('G', states(getGearboxState())) + .where('F', frames(Materials.Steel)) + .where('C', states(getCasingState()) + .or(abilities(MultiblockAbility.IMPORT_ITEMS).setMaxGlobalLimited(1)) + .or(autoAbilities(true, false))) + .where('E', states(getCasingState()) + .or(abilities(MultiblockAbility.INPUT_ENERGY)).setMinGlobalLimited(1).setMaxGlobalLimited(2)) + .where('O', abilities(MultiblockAbility.EXPORT_FLUIDS)) + .build(); + } + + @Override + public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { + return Textures.SOLID_STEEL_CASING; + } + + protected static IBlockState getCasingState() { + return MetaBlocks.METAL_CASING.getState(MetalCasingType.STEEL_SOLID); + } + + protected static IBlockState getPipeCasingState() { + return MetaBlocks.BOILER_CASING.getState(BoilerCasingType.STEEL_PIPE); + } + + protected static IBlockState getGearboxState() { + return MetaBlocks.TURBINE_CASING.getState(TurbineCasingType.STEEL_GEARBOX); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.large_fluid_pump.tooltip.1")); + tooltip.add(I18n.format("gregtech.machine.large_fluid_pump.tooltip.2")); + super.addInformation(stack, player, tooltip, advanced); + tooltip.add(TooltipHelper.RAINBOW_SLOW + I18n.format("gregtech.machine.perfect_oc", new Object[0])); + } + @Override + protected void addDisplayText(List textList) { + super.addDisplayText(textList); + EnumFacing leftSide = RelativeDirection.LEFT + .getRelativeFacing( + getFrontFacing(), + getUpwardsFacing(), + isFlipped() + ); + EnumFacing backSide = RelativeDirection.BACK + .getRelativeFacing( + getFrontFacing(), + getUpwardsFacing(), + isFlipped() + ); + BlockPos tempPos = getPos().offset(leftSide, 4).offset(backSide); + int yLevel = getPos().getY(); + String biome = getWorld().getBiome(tempPos).biomeName; + textList.add(new TextComponentTranslation("susy.large_fluid_pump.y_level", yLevel).setStyle(new Style().setColor(TextFormatting.YELLOW))); + textList.add(new TextComponentTranslation("susy.large_fluid_pump.biome", biome).setStyle(new Style().setColor(TextFormatting.YELLOW))); + } + + @Nonnull + @Override + protected ICubeRenderer getFrontOverlay() { + return SusyTextures.OCEANIC_DRILL_OVERLAY; + } + + /** + * A custom recipeLogic class, for adding our check for biomes + * This can be moved out to a stand-alone class. + * But generally speaking if you do not plan to re-use this, making it an inner class should be fine. + * CEu itself has many such cases. + */ + public static class LargePumpRecipeLogic extends MultiblockRecipeLogic { + + public LargePumpRecipeLogic(RecipeMapMultiblockController tileEntity) { + super(tileEntity, true); + } + + /** + * Overriding this to add our own custom checks + * Don't forget super calls + */ + @Override + public boolean checkRecipe(@NotNull Recipe recipe) { + return checkHeightRequirement() && checkBiomeRequirement(recipe) && super.checkRecipe(recipe); + } + + public boolean checkHeightRequirement() { + return getMetaTileEntity().getPos().getY() == 64; + } + + /** + * This is a method for biome checking + */ + public boolean checkBiomeRequirement(@NotNull Recipe recipe) { + if (!recipe.hasProperty(BiomeProperty.getInstance())) return true; + EnumFacing leftSide = RelativeDirection.LEFT + .getRelativeFacing( + getMetaTileEntity().getFrontFacing(), + ((MultiblockControllerBase) getMetaTileEntity()).getUpwardsFacing(), + ((MultiblockControllerBase) getMetaTileEntity()).isFlipped() + ); + EnumFacing backSide = RelativeDirection.BACK + .getRelativeFacing( + getMetaTileEntity().getFrontFacing(), + ((MultiblockControllerBase) getMetaTileEntity()).getUpwardsFacing(), + ((MultiblockControllerBase) getMetaTileEntity()).isFlipped() + ); + BlockPos tempPos = getMetaTileEntity().getPos().offset(leftSide, 4).offset(backSide); + return recipe.getProperty(BiomeProperty.getInstance(), BiomeProperty.BiomePropertyList.EMPTY_LIST) + .checkBiome(getMetaTileEntity().getWorld().getBiome(tempPos)); + } + + @Override + public int getParallelLimit() { + return 256; + } + } + +} diff --git a/src/main/resources/assets/susy/lang/en_us.lang b/src/main/resources/assets/susy/lang/en_us.lang index a9c781054..f6b7ed481 100644 --- a/src/main/resources/assets/susy/lang/en_us.lang +++ b/src/main/resources/assets/susy/lang/en_us.lang @@ -256,6 +256,9 @@ gregtech.machine.primitive_mud_pump.name=Primitive Mud Pump gregtech.machine.primitive_mud_pump.tooltip=Works only in River biomes between Y=64 and Y=80 gregtech.machine.basic_steam_turbine.name=Large Steam Turbine gregtech.machine.basic_gas_turbine.name=Large Gas Turbine +gregtech.machine.large_fluid_pump.name=Large Fluid Pump +gregtech.machine.large_fluid_pump.tooltip.1=This would definitely affect the local trout population. +gregtech.machine.large_fluid_pump.tooltip.2=Only works when the controller is at Y=64 and the bottom Steel Pipe Casing is located in the right biome. gregtech.machine.ocean_pumper.name=Ocean Pumper gregtech.machine.ocean_pumper.tooltip=Works only in Ocean biomes between Y=70 and Y=75 gregtech.machine.advanced_arc_furnace.name=Advanced Arc Furnace @@ -709,6 +712,7 @@ recipemap.gravity_separator=Gravity Separation recipemap.spinning.name=Textile Spinning recipemap.large_steam_turbine.name=Large Steam Turbine recipemap.primitive_smelter.name=Primitive Smelting +recipemap.large_fluid_pump.name=Large Fluid Pump gregtech.multiblock.primitive_mud_pump.description=The Primitive Mud Pump is a Steam Era multiblock that collects mud once per second, but only if it is in a river biome, and when the controller is between Y = 64 and Y = 80 (Inclusive). It can use a Pump, ULV, or LV Output Hatch. gregtech.multiblock.ocean_pumper.description=The Ocean Pumper is an electrically powered multiblock that collects a base amount of 8,000 L Seawater per second (at MV), but only if it is in an ocean biome, and when the controller is between Y = 70 and Y = 75 (Inclusive). It needs an output hatch, a maintenance hatch, and an energy input hatch. @@ -798,12 +802,18 @@ susy.ocean_pumper.full=Tanks are Full! susy.ocean_pumper.drainrate=Current Pumping Rate: %s susy.wrongbiome=Machine can not work in this biome! susy.weather_resistance=ยง2Will not explode from water, lava, fire or rain. +susy.large_fluid_pump.y_level=Current Controller Y level: Y=%s +susy.large_fluid_pump.biome=Current bottom Pipe Casing biome: %s # Latex Logs gregtech.block_group_members.latex_logs.name=Rubber Log # Extra recipe info susy.recipe.dimensions=Dimensions: %s +susy.recipe.biomes=Biomes: %s +susy.recipe.biomes_blocked=Blocked Biomes: %s +susy.recipe.biomeTypes=BiomeTypes: %s +susy.recipe.biomeTypes_blocked=Blocked BiomeTypes: %s # Commands