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);
}
}
}
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;
}
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;
}
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);
}
Aggregations