Search in sources :

Example 1 with CropBlockStateDefinition

use of com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition 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 CropBlockStateDefinition

use of com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition in project Almura by AlmuraDev.

the class CropBlockImpl method canUseBonemeal.

@Override
public boolean canUseBonemeal(final World world, final Random random, final BlockPos pos, final IBlockState state) {
    if (!world.isRemote) {
        if (!this.isMaxAge(state)) {
            // TODO Maybe best to move this into an interact listener and make this hook do nothing
            final CropBlockStateDefinition definition = this.definition(state);
            if (definition.fertilizer != null) {
                final Fertilizer fertilizer = definition.fertilizer;
                // TODO Pre-1.13, this is just a mess...maybe need a Deprecated "LazyItemState" that checks data
                final DoubleRange chanceRange = fertilizer.getOrLoadChanceRangeForItem(new ItemStack(Items.DYE, 1, 15));
                if (chanceRange != null) {
                    return RANDOM.nextDouble() <= (chanceRange.random(RANDOM) / 100);
                }
            }
        }
    }
    return false;
}
Also used : CropBlockStateDefinition(com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition) DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) ItemStack(net.minecraft.item.ItemStack) Fertilizer(com.almuradev.content.type.block.type.crop.processor.fertilizer.Fertilizer)

Example 3 with CropBlockStateDefinition

use of com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition in project Almura by AlmuraDev.

the class CropBlockImpl method isFertile.

@Override
public boolean isFertile(final World world, final BlockPos pos) {
    final CropBlockStateDefinition definition = this.definition(world.getBlockState(pos.up()));
    final IBlockState soilState = world.getBlockState(pos);
    if (definition.hydration == null) {
        if (soilState.getBlock() == net.minecraft.init.Blocks.FARMLAND) {
            return ((Integer) soilState.getValue(BlockFarmland.MOISTURE)) > 0;
        }
        // Not farmland? Seed said our soil is something else so just assume always fertile since their config lacked it
        return true;
    } else {
        final int maxRadius = definition.hydration.getMaxRadius();
        for (final BlockPos.MutableBlockPos inRange : BlockPos.getAllInBoxMutable(pos.add(-maxRadius, 0, -maxRadius), pos.add(maxRadius, 0, maxRadius))) {
            final IBlockState inRangeState;
            // lets you do stone soil and "hydrated" by stone
            if (inRange.equals(pos)) {
                inRangeState = soilState;
            } else {
                inRangeState = world.getBlockState(inRange);
            }
            if (definition.hydration.doesStateMatch(inRangeState)) {
                return true;
            }
        }
    }
    return false;
}
Also used : PropertyInteger(net.minecraft.block.properties.PropertyInteger) CropBlockStateDefinition(com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition) IBlockState(net.minecraft.block.state.IBlockState) BlockPos(net.minecraft.util.math.BlockPos)

Example 4 with CropBlockStateDefinition

use of com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition in project Almura by AlmuraDev.

the class CropBlockImpl method getExplosionResistance.

@Override
public float getExplosionResistance(final World world, final BlockPos pos, @Nullable final Entity exploder, final Explosion explosion) {
    final IBlockState state = world.getBlockState(pos);
    final CropBlockStateDefinition definition = this.definition(state);
    return definition.resistance.isPresent() ? (float) definition.resistance.getAsDouble() : super.getExplosionResistance(exploder);
}
Also used : CropBlockStateDefinition(com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition) IBlockState(net.minecraft.block.state.IBlockState)

Aggregations

CropBlockStateDefinition (com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition)4 DoubleRange (com.almuradev.toolbox.util.math.DoubleRange)2 IBlockState (net.minecraft.block.state.IBlockState)2 Fertilizer (com.almuradev.content.type.block.type.crop.processor.fertilizer.Fertilizer)1 Growth (com.almuradev.content.type.block.type.crop.processor.growth.Growth)1 Nullable (javax.annotation.Nullable)1 PropertyInteger (net.minecraft.block.properties.PropertyInteger)1 ItemStack (net.minecraft.item.ItemStack)1 BlockPos (net.minecraft.util.math.BlockPos)1 Biome (net.minecraft.world.biome.Biome)1