Search in sources :

Example 1 with DoubleRange

use of com.almuradev.toolbox.util.math.DoubleRange 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)) {
            // Return TRUE always when in Dev mode!
            if (SpongeImplHooks.isDeobfuscatedEnvironment()) {
                return true;
            }
            // 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 2 with DoubleRange

use of com.almuradev.toolbox.util.math.DoubleRange 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_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) {
            float biomeTemperature = this.round(biome.getTemperature(pos), 2);
            if (!temperatureRequiredRange.contains(biomeTemperature)) {
                // Range Check
                rollback = true;
            }
            if (biomeTemperature < temperatureRequiredRange.min()) {
                // Check for additional heat source
                if (hasAdditionalLightSource(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);
        final boolean hasAdditionalLightSource = hasAdditionalLightSource(world, pos, 1);
        // 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 = !hasAdditionalLightSource;
            }
            if (canRollback && rollback) {
                if (world.canSeeSky(pos) && !world.isDaytime()) {
                    // 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 biomeGrowthChance = growth.getOrLoadChanceRangeForBiome(biome);
            if (biomeGrowthChance == null || biomeGrowthChance.max() == 0) {
                return;
            }
            final double randomValue = RANDOM.nextDouble();
            double growthChance = (biomeGrowthChance.random(RANDOM) / 100);
            if (hasAdditionalLightSource) {
                // Double the rate of growth if the heat lamp is detected.
                growthChance = growthChance * 2;
            }
            // Can we grow? Yes? Awesome!
            if (randomValue <= growthChance && this.isGrowthEven(world, pos, age)) {
                // If growth will be even, grow
                world.setBlockState(pos, this.withAge(age + 1), 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_CLIENTS);
                    if (!world.isRemote) {
                        world.playEvent(2005, pos, 0);
                    }
                    ForgeHooks.onCropsGrowPost(world, pos, state, null);
                }
            }
        }
    }
    if (canRollback && rollback) {
        if (!world.isRemote) {
            // Smoke
            world.playEvent(2000, pos, 10);
        }
        if (age > 0) {
            world.setBlockState(pos, this.withAge(age - 1), 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_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 3 with DoubleRange

use of com.almuradev.toolbox.util.math.DoubleRange in project Almura by AlmuraDev.

the class LeafBlockImpl method updateSpreadTick.

private void updateSpreadTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
    if (worldIn.isRemote) {
        return;
    }
    final IBlockState actualBlock = worldIn.getBlockState(pos);
    final Spread spread = this.definition.spread;
    if (spread == null) {
        return;
    }
    if (actualBlock.getBlock() != this) {
        return;
    }
    final Biome biome = worldIn.getBiome(pos);
    final DoubleRange chanceRoll = spread.getOrLoadChanceRangeForBiome(biome);
    if (chanceRoll == null) {
        return;
    }
    if (!(rand.nextDouble() <= (chanceRoll.random(rand) / 100))) {
        return;
    }
    for (final EnumFacing facing : EnumFacing.values()) {
        final BlockPos offset = pos.offset(facing);
        final IBlockState offsetBlock = worldIn.getBlockState(offset);
        if (offsetBlock.getBlock() == Blocks.AIR) {
            worldIn.setBlockState(offset, spread.getBlock().get());
            worldIn.playEvent(2005, pos, 0);
            break;
        }
    }
}
Also used : DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) Spread(com.almuradev.content.type.block.type.leaf.processor.spread.Spread) IBlockState(net.minecraft.block.state.IBlockState) Biome(net.minecraft.world.biome.Biome) EnumFacing(net.minecraft.util.EnumFacing) BlockPos(net.minecraft.util.math.BlockPos)

Example 4 with DoubleRange

use of com.almuradev.toolbox.util.math.DoubleRange in project Almura by AlmuraDev.

the class LeafBlockImpl method updateTick.

@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
    if (!worldIn.isRemote) {
        if (((Boolean) state.getValue(CHECK_DECAY)).booleanValue() && ((Boolean) state.getValue(DECAYABLE)).booleanValue()) {
            int i = 4;
            int j = 5;
            int k = pos.getX();
            int l = pos.getY();
            int i1 = pos.getZ();
            int j1 = 32;
            int k1 = 1024;
            int l1 = 16;
            if (((BlockLeavesAccessor) (Object) this).accessor$getSurroundings() == null) {
                ((BlockLeavesAccessor) (Object) this).accessor$setSurroundings(new int[32768]);
            }
            final int[] surroundings = ((BlockLeavesAccessor) (Object) this).accessor$getSurroundings();
            // Forge: prevent decaying leaves from updating neighbors and loading unloaded chunks
            if (!worldIn.isAreaLoaded(pos, 1))
                return;
            if (// Forge: extend range from 5 to 6 to account for neighbor checks in world.markAndNotifyBlock -> world.updateObservingBlocksAt
            worldIn.isAreaLoaded(pos, 6)) {
                BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
                for (int i2 = -4; i2 <= 4; ++i2) {
                    for (int j2 = -4; j2 <= 4; ++j2) {
                        for (int k2 = -4; k2 <= 4; ++k2) {
                            IBlockState iblockstate = worldIn.getBlockState(blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2));
                            Block block = iblockstate.getBlock();
                            // Almura Start - Ask the leaf for a block that can keep it from decaying. Allow Vanilla logs to have first say
                            boolean preventDecay = block.canSustainLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2));
                            if (!preventDecay) {
                                final PreventDecay pDecay = this.definition.preventDecay;
                                if (pDecay != null) {
                                    final DoubleRange chanceRoll = pDecay.getOrLoadChanceRangeForBiome(worldIn.getBiome(blockpos$mutableblockpos));
                                    if (chanceRoll != null) {
                                        if ((rand.nextDouble() >= (chanceRoll.random(rand) / 100))) {
                                        // if (pDecay.getBlock().partialTest(iblockstate)) {
                                        // preventDecay = true;
                                        // }
                                        }
                                    }
                                }
                            }
                            if (!preventDecay) {
                                // Almura End
                                if (block.isLeaves(iblockstate, worldIn, blockpos$mutableblockpos.setPos(k + i2, l + j2, i1 + k2))) {
                                    surroundings[(i2 + 16) * 1024 + (j2 + 16) * 32 + k2 + 16] = -2;
                                } else {
                                    surroundings[(i2 + 16) * 1024 + (j2 + 16) * 32 + k2 + 16] = -1;
                                }
                            } else {
                                surroundings[(i2 + 16) * 1024 + (j2 + 16) * 32 + k2 + 16] = 0;
                            }
                        }
                    }
                }
                for (int i3 = 1; i3 <= 4; ++i3) {
                    for (int j3 = -4; j3 <= 4; ++j3) {
                        for (int k3 = -4; k3 <= 4; ++k3) {
                            for (int l3 = -4; l3 <= 4; ++l3) {
                                if (surroundings[(j3 + 16) * 1024 + (k3 + 16) * 32 + l3 + 16] == i3 - 1) {
                                    if (surroundings[(j3 + 16 - 1) * 1024 + (k3 + 16) * 32 + l3 + 16] == -2) {
                                        surroundings[(j3 + 16 - 1) * 1024 + (k3 + 16) * 32 + l3 + 16] = i3;
                                    }
                                    if (surroundings[(j3 + 16 + 1) * 1024 + (k3 + 16) * 32 + l3 + 16] == -2) {
                                        surroundings[(j3 + 16 + 1) * 1024 + (k3 + 16) * 32 + l3 + 16] = i3;
                                    }
                                    if (surroundings[(j3 + 16) * 1024 + (k3 + 16 - 1) * 32 + l3 + 16] == -2) {
                                        surroundings[(j3 + 16) * 1024 + (k3 + 16 - 1) * 32 + l3 + 16] = i3;
                                    }
                                    if (surroundings[(j3 + 16) * 1024 + (k3 + 16 + 1) * 32 + l3 + 16] == -2) {
                                        surroundings[(j3 + 16) * 1024 + (k3 + 16 + 1) * 32 + l3 + 16] = i3;
                                    }
                                    if (surroundings[(j3 + 16) * 1024 + (k3 + 16) * 32 + (l3 + 16 - 1)] == -2) {
                                        surroundings[(j3 + 16) * 1024 + (k3 + 16) * 32 + (l3 + 16 - 1)] = i3;
                                    }
                                    if (surroundings[(j3 + 16) * 1024 + (k3 + 16) * 32 + l3 + 16 + 1] == -2) {
                                        surroundings[(j3 + 16) * 1024 + (k3 + 16) * 32 + l3 + 16 + 1] = i3;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int l2 = surroundings[16912];
            if (l2 >= 0) {
                worldIn.setBlockState(pos, state.withProperty(CHECK_DECAY, Boolean.valueOf(false)), 4);
            } else {
                ((BlockLeavesAccessor) (Object) this).invoker$destroy(worldIn, pos);
            }
        }
    }
    this.updateSpreadTick(worldIn, pos, state, rand);
}
Also used : DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) BlockLeavesAccessor(com.almuradev.almura.asm.mixin.accessors.block.BlockLeavesAccessor) IBlockState(net.minecraft.block.state.IBlockState) PreventDecay(com.almuradev.content.type.block.type.leaf.processor.preventdecay.PreventDecay) Block(net.minecraft.block.Block) StateMappedBlock(com.almuradev.content.type.block.StateMappedBlock) BlockPos(net.minecraft.util.math.BlockPos)

Example 5 with DoubleRange

use of com.almuradev.toolbox.util.math.DoubleRange in project Almura by AlmuraDev.

the class PreventDecay method getOrLoadChanceRangeForBiome.

@Nullable
public DoubleRange getOrLoadChanceRangeForBiome(final Biome biome) {
    @Nullable DoubleRange found = this.biomeChanceRanges.get(biome);
    if (found == null) {
        for (final Map.Entry<FunctionPredicate<Biome, ResourceLocation>, DoubleRange> entry : this.biomeChancePredicates.entrySet()) {
            final FunctionPredicate<Biome, ResourceLocation> predicate = entry.getKey();
            if (predicate.test(biome)) {
                final DoubleRange range = entry.getValue();
                this.biomeChanceRanges.put(biome, range);
                found = range;
                break;
            }
        }
    }
    if (found == null && this.globalChanceRange != null) {
        this.biomeChanceRanges.put(biome, this.globalChanceRange);
        found = this.globalChanceRange;
    }
    return found;
}
Also used : DoubleRange(com.almuradev.toolbox.util.math.DoubleRange) Biome(net.minecraft.world.biome.Biome) ResourceLocation(net.minecraft.util.ResourceLocation) FunctionPredicate(com.almuradev.content.component.predicate.FunctionPredicate) HashMap(java.util.HashMap) Map(java.util.Map) Nullable(javax.annotation.Nullable) Nullable(javax.annotation.Nullable)

Aggregations

DoubleRange (com.almuradev.toolbox.util.math.DoubleRange)18 BlockPos (net.minecraft.util.math.BlockPos)9 Biome (net.minecraft.world.biome.Biome)8 Map (java.util.Map)7 Nullable (javax.annotation.Nullable)7 World (net.minecraft.world.World)7 FunctionPredicate (com.almuradev.content.component.predicate.FunctionPredicate)6 HashMap (java.util.HashMap)6 Random (java.util.Random)6 ResourceLocation (net.minecraft.util.ResourceLocation)5 IBlockState (net.minecraft.block.state.IBlockState)4 SubscribeEvent (net.minecraftforge.fml.common.eventhandler.SubscribeEvent)4 CropBlockStateDefinition (com.almuradev.content.type.block.type.crop.state.CropBlockStateDefinition)3 Growth (com.almuradev.content.type.block.type.crop.processor.growth.Growth)2 Block (net.minecraft.block.Block)2 ItemStack (net.minecraft.item.ItemStack)2 BlockLeavesAccessor (com.almuradev.almura.asm.mixin.accessors.block.BlockLeavesAccessor)1 IMixinBlockCrops (com.almuradev.almura.feature.complex.item.almanac.asm.interfaces.IMixinBlockCrops)1 ClientboundWorldPositionInformationPacket (com.almuradev.almura.feature.complex.item.almanac.network.ClientboundWorldPositionInformationPacket)1 MathUtil (com.almuradev.almura.shared.util.MathUtil)1