Search in sources :

Example 1 with Growth

use of com.almuradev.content.type.block.type.crop.processor.growth.Growth in project Almura by AlmuraDev.

the class CropBlockImpl method advanceState.

private void advanceState(final World world, final BlockPos pos, final IBlockState state, final boolean fertilizer) {
    final int age = this.getAge(state);
    final CropBlockStateDefinition definition = this.state(age);
    if (fertilizer) {
        world.setBlockState(pos, this.withAge(age + 1), BlockUpdateFlag.UPDATE_NEIGHBORS | BlockUpdateFlag.UPDATE_CLIENTS);
        return;
    }
    final boolean isMaxAge = this.isMaxAge(state);
    final boolean canRollback = definition.canRollback;
    if (isMaxAge) {
        // && !canRollback) { // Remove 3/22/2018 to prevent generated crops from rolling back.
        return;
    }
    boolean rollback = false;
    // Crop soil isn't fertile? Don't grow and rollback if applicable
    if (!this.isFertile(world, pos.down())) {
        rollback = true;
    }
    // Check if its time to perform a growth tick
    @Nullable final Growth growth = definition.growth;
    if (!rollback && growth != null) {
        final Biome biome = world.getBiome(pos);
        // Temperature of biome isn't in required range? Don't grow and rollback if applicable
        // TODO Should fertilizer be blocked from advancing a crop if out of temperature? Or should it be allowed
        // TODO and punish the user afterwards (might be more amusing that way)
        final DoubleRange temperatureRequiredRange = growth.getOrLoadTemperatureRequiredRangeForBiome(biome);
        if (temperatureRequiredRange != null) {
            final float biomeTemperature = biome.getTemperature(pos);
            if (!temperatureRequiredRange.contains(biomeTemperature)) {
                // Range Check
                rollback = true;
            }
            if (biomeTemperature < temperatureRequiredRange.min()) {
                // Check for additional heat source
                if (hasAdditionalSource(world, pos, 1)) {
                    rollback = false;
                }
            }
        }
        // Light of biome isn't in required range? Don't grow and rollback if applicable
        final DoubleRange light = growth.getOrLoadLightRangeForBiome(biome);
        // Skip this section if rollback is true because a Tempoerature fail should never be overridden by light.
        if (!rollback && light != null && world.isAreaLoaded(pos, 1)) {
            final int minLight = (int) light.min();
            final int maxLight = (int) light.max();
            final int lightLevel = world.getLightFromNeighbors(pos);
            if (lightLevel < minLight || lightLevel > maxLight) {
                rollback = !hasAdditionalSource(world, pos, 2);
            }
            if (canRollback && rollback) {
                if (world.canSeeSky(pos)) {
                    final int worldLight = world.getLightFor(EnumSkyBlock.SKY, pos) - world.getSkylightSubtracted();
                    if (worldLight < 6) {
                        // Crops go to sleep on a routine if their lightLevel is predictable
                        // Prevent a crop from rolling back in the middle of the night if it can see sky.
                        rollback = false;
                    }
                }
            }
        }
        if (!rollback && !this.isMaxAge(state)) {
            final DoubleRange change = growth.getOrLoadChanceRangeForBiome(biome);
            if (change == null || change.max() == 0) {
                return;
            }
            // Can we grow? Yes? Awesome!
            if (RANDOM.nextDouble() <= (change.random(RANDOM) / 100) && this.isGrowthEven(world, pos, age)) {
                // If growth will be even, grow
                world.setBlockState(pos, this.withAge(age + 1), BlockUpdateFlag.UPDATE_NEIGHBORS | BlockUpdateFlag.UPDATE_CLIENTS);
                if (ForgeHooks.onCropsGrowPre(world, pos, state, true)) {
                    // If growth will be even, grow
                    world.setBlockState(pos, this.withAge(age + 1), BlockUpdateFlag.UPDATE_NEIGHBORS | BlockUpdateFlag.UPDATE_CLIENTS);
                    if (!world.isRemote) {
                        world.playEvent(2005, pos, 0);
                    }
                    ForgeHooks.onCropsGrowPost(world, pos, state, null);
                }
            }
        }
    }
    if (canRollback && rollback) {
        if (age > 0) {
            world.setBlockState(pos, this.withAge(age - 1), BlockUpdateFlag.UPDATE_NEIGHBORS | BlockUpdateFlag.UPDATE_CLIENTS);
        } else {
            // They let the crop continue to roll back? Tough, they just lost it
            // TODO Dockter, do you want to show a generic "dead crop block"
            world.setBlockState(pos, Blocks.AIR.getDefaultState(), BlockUpdateFlag.UPDATE_NEIGHBORS | BlockUpdateFlag.UPDATE_CLIENTS);
        }
    }
}
Also used : CropBlockStateDefinition(com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition) DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) Biome(net.minecraft.world.biome.Biome) Growth(com.almuradev.content.type.block.type.crop.processor.growth.Growth) Nullable(javax.annotation.Nullable)

Example 2 with Growth

use of com.almuradev.content.type.block.type.crop.processor.growth.Growth in project Almura by AlmuraDev.

the class IngameFarmersAlmanac method loadProperties.

@SuppressWarnings("unchecked")
private void loadProperties(World world, IBlockState blockState, BlockPos blockPos) {
    final Hydration hydration = getHydrationDefinition(blockState).orElse(null);
    if (hydration != null) {
        this.addLineLabel(Text.of(TextColors.WHITE, "Hydrated by:"));
        hydration.blockStates().forEach(bs -> {
            this.addLineLabel(Text.of(TextColors.WHITE, "- ", bs.block().getLocalizedName()), 2, false);
            bs.properties().forEach(property -> bs.value(property).ifPresent(stateValue -> {
                final String formattedValue;
                if (stateValue instanceof RangeStateValue) {
                    final RangeStateValue rangeStateValue = (RangeStateValue) stateValue;
                    formattedValue = numberFormat.format(rangeStateValue.min()) + "-" + numberFormat.format(rangeStateValue.max());
                } else {
                    final Comparable rawValue = stateValue.get((IProperty) property);
                    formattedValue = rawValue == null ? "" : rawValue.toString();
                }
                this.addLineLabel(this.getGenericPropertyText("- " + property.getName(), formattedValue), 6, false);
            }));
        });
        this.addLineLabel(this.getGenericPropertyText("Hydration Radius", String.valueOf(hydration.getMaxRadius())));
    }
    // Growth stage
    getGrowthStage(blockState).ifPresent(growthStage -> this.addLineLabel(this.getGenericPropertyText("Growth Stage", String.format("%d of %d", growthStage.getFirst(), growthStage.getSecond()))));
    // Ground moisture
    final int moistureLevel = getMoistureLevel(blockState);
    final boolean isFertile = moistureLevel > 0;
    final TextColor fertileColor = isFertile ? TextColors.DARK_GREEN : TextColors.RED;
    this.addLineLabel(Text.of(TextColors.WHITE, "Moisture: ", fertileColor, isFertile ? "Fertile" : "Too dry"));
    // Ground temperature
    final DoubleRange temperatureRange = getTemperatureRange(world, blockState, blockPos).orElse(null);
    if (temperatureRange != null) {
        this.addLineLabel(Text.of(TextColors.WHITE, "Ground Temperature: ", (temperatureRange.min() == -1 || temperatureRange.max() == -1) ? TextColors.RED : TextColors.DARK_GREEN, numberFormat.format(message.biomeTemperature)));
        this.addLineLabel(this.getGenericPropertyText("Required", String.format("%s-%s", numberFormat.format(temperatureRange.min()), numberFormat.format(temperatureRange.max()))), 2, false);
    }
    // Biome rain
    this.addLineLabel(Text.of(TextColors.WHITE, "Rain: ", message.biomeRainfall > 0.4 ? TextColors.DARK_GREEN : TextColors.RED, numberFormat.format(message.biomeRainfall)));
    // Sunlight value
    final int sunlight = world.getLightFor(EnumSkyBlock.SKY, blockPos) - world.getSkylightSubtracted();
    this.addLineLabel(this.getGenericPropertyText("Sunlight", String.valueOf(sunlight)));
    // Area light value
    final DoubleRange lightRange = getLightRange(world, blockState, blockPos).orElse(null);
    if (lightRange != null) {
        final int lightValue = world.getLightFor(EnumSkyBlock.SKY, blockPos);
        final TextColor valueColor = lightValue < 6 ? (sunlight < 6 ? TextColors.RED : TextColors.YELLOW) : TextColors.DARK_GREEN;
        this.addLineLabel(Text.of(TextColors.WHITE, "Area light: ", valueColor, String.valueOf(lightValue)));
        this.addLineLabel(this.getGenericPropertyText("Required", String.format("%s-%s", numberFormat.format(lightRange.min()), numberFormat.format(lightRange.max()))), 2, false);
    }
    // Can Die
    this.addLineLabel(this.getGenericPropertyText("Can Die", String.valueOf(canRollback(blockState))));
    // Harvest Tool
    final String harvestTool = blockState.getBlock().getHarvestTool(blockState);
    if (harvestTool != null && !harvestTool.isEmpty()) {
        addLineLabel(this.getGenericPropertyText("Harvested by", harvestTool));
    }
}
Also used : BlockCrops(net.minecraft.block.BlockCrops) BlockFarmland(net.minecraft.block.BlockFarmland) ClientboundWorldPositionInformationPacket(com.almuradev.almura.feature.complex.item.almanac.network.ClientboundWorldPositionInformationPacket) WorldClient(net.minecraft.client.multiplayer.WorldClient) UIFormContainer(com.almuradev.almura.shared.client.ui.component.UIFormContainer) UIButtonBuilder(com.almuradev.almura.shared.client.ui.component.button.UIButtonBuilder) UIComponent(net.malisis.core.client.gui.component.UIComponent) NumberFormat(java.text.NumberFormat) ItemStack(net.minecraft.item.ItemStack) RayTraceResult(net.minecraft.util.math.RayTraceResult) WorldType(net.minecraft.world.WorldType) IProperty(net.minecraft.block.properties.IProperty) Block(net.minecraft.block.Block) Text(org.spongepowered.api.text.Text) TextColor(org.spongepowered.api.text.format.TextColor) Minecraft(net.minecraft.client.Minecraft) FontColors(com.almuradev.almura.shared.client.ui.FontColors) Anchor(net.malisis.core.client.gui.Anchor) TextColors(org.spongepowered.api.text.format.TextColors) Growth(com.almuradev.content.type.block.type.crop.processor.growth.Growth) UIScrollBar(net.malisis.core.client.gui.component.control.UIScrollBar) UIButton(net.malisis.core.client.gui.component.interaction.UIButton) RangeStateValue(com.almuradev.content.type.block.state.value.RangeStateValue) SimpleScreen(com.almuradev.almura.shared.client.ui.screen.SimpleScreen) CropBlockStateDefinition(com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition) IMixinBlockCrops(com.almuradev.almura.feature.complex.item.almanac.asm.interfaces.IMixinBlockCrops) UILabel(net.malisis.core.client.gui.component.decoration.UILabel) UIBackgroundContainer(net.malisis.core.client.gui.component.container.UIBackgroundContainer) World(net.minecraft.world.World) DecimalFormat(java.text.DecimalFormat) PropertyInteger(net.minecraft.block.properties.PropertyInteger) Hydration(com.almuradev.content.type.block.type.crop.processor.hydration.Hydration) BlockPos(net.minecraft.util.math.BlockPos) Tuple(org.spongepowered.api.util.Tuple) Mouse(org.lwjgl.input.Mouse) UISeparator(net.malisis.core.client.gui.component.decoration.UISeparator) IBlockState(net.minecraft.block.state.IBlockState) TextSerializers(org.spongepowered.api.text.serializer.TextSerializers) UIImage(net.malisis.core.client.gui.component.decoration.UIImage) EnumSkyBlock(net.minecraft.world.EnumSkyBlock) Optional(java.util.Optional) CropBlockImpl(com.almuradev.content.type.block.type.crop.CropBlockImpl) DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) UISlimScrollbar(net.malisis.core.client.gui.component.control.UISlimScrollbar) RangeStateValue(com.almuradev.content.type.block.state.value.RangeStateValue) DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) Hydration(com.almuradev.content.type.block.type.crop.processor.hydration.Hydration) IProperty(net.minecraft.block.properties.IProperty) TextColor(org.spongepowered.api.text.format.TextColor)

Aggregations

Growth (com.almuradev.content.type.block.type.crop.processor.growth.Growth)2 CropBlockStateDefinition (com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition)2 DoubleRange (com.almuradev.toolbox.util.math.DoubleRange)2 IMixinBlockCrops (com.almuradev.almura.feature.complex.item.almanac.asm.interfaces.IMixinBlockCrops)1 ClientboundWorldPositionInformationPacket (com.almuradev.almura.feature.complex.item.almanac.network.ClientboundWorldPositionInformationPacket)1 FontColors (com.almuradev.almura.shared.client.ui.FontColors)1 UIFormContainer (com.almuradev.almura.shared.client.ui.component.UIFormContainer)1 UIButtonBuilder (com.almuradev.almura.shared.client.ui.component.button.UIButtonBuilder)1 SimpleScreen (com.almuradev.almura.shared.client.ui.screen.SimpleScreen)1 RangeStateValue (com.almuradev.content.type.block.state.value.RangeStateValue)1 CropBlockImpl (com.almuradev.content.type.block.type.crop.CropBlockImpl)1 Hydration (com.almuradev.content.type.block.type.crop.processor.hydration.Hydration)1 DecimalFormat (java.text.DecimalFormat)1 NumberFormat (java.text.NumberFormat)1 Optional (java.util.Optional)1 Nullable (javax.annotation.Nullable)1 Anchor (net.malisis.core.client.gui.Anchor)1 UIComponent (net.malisis.core.client.gui.component.UIComponent)1 UIBackgroundContainer (net.malisis.core.client.gui.component.container.UIBackgroundContainer)1 UIScrollBar (net.malisis.core.client.gui.component.control.UIScrollBar)1