Search in sources :

Example 1 with ClimateRange

use of net.dries007.tfc.util.climate.ClimateRange in project TerraFirmaCraft by TerraFirmaCraft.

the class SpreadingBushBlock method addHoeOverlayInfo.

@Override
public void addHoeOverlayInfo(Level level, BlockPos pos, BlockState state, List<Component> text, boolean isDebug) {
    final BlockPos sourcePos = pos.below();
    final ClimateRange range = climateRange.get();
    text.add(FarmlandBlock.getHydrationTooltip(level, sourcePos, range, false));
    text.add(FarmlandBlock.getTemperatureTooltip(level, sourcePos, range, false));
}
Also used : ClimateRange(net.dries007.tfc.util.climate.ClimateRange) BlockPos(net.minecraft.core.BlockPos)

Example 2 with ClimateRange

use of net.dries007.tfc.util.climate.ClimateRange in project TerraFirmaCraft by TerraFirmaCraft.

the class StationaryBerryBushBlock method addHoeOverlayInfo.

@Override
public void addHoeOverlayInfo(Level level, BlockPos pos, BlockState state, List<Component> text, boolean isDebug) {
    final BlockPos sourcePos = pos.below();
    final ClimateRange range = climateRange.get();
    text.add(FarmlandBlock.getHydrationTooltip(level, sourcePos, range, false));
    text.add(FarmlandBlock.getTemperatureTooltip(level, sourcePos, range, false));
}
Also used : ClimateRange(net.dries007.tfc.util.climate.ClimateRange) BlockPos(net.minecraft.core.BlockPos)

Example 3 with ClimateRange

use of net.dries007.tfc.util.climate.ClimateRange in project TerraFirmaCraft by TerraFirmaCraft.

the class DeadCropBlock method addHoeOverlayInfo.

@Override
public void addHoeOverlayInfo(Level level, BlockPos pos, BlockState state, List<Component> text, boolean isDebug) {
    final ClimateRange range = climateRange.get();
    text.add(FarmlandBlock.getHydrationTooltip(level, pos.below(), range, false));
    text.add(FarmlandBlock.getTemperatureTooltip(level, pos, range, false));
    if (state.getValue(MATURE))
        text.add(new TranslatableComponent("tfc.tooltip.farmland.mature"));
}
Also used : ClimateRange(net.dries007.tfc.util.climate.ClimateRange) TranslatableComponent(net.minecraft.network.chat.TranslatableComponent)

Example 4 with ClimateRange

use of net.dries007.tfc.util.climate.ClimateRange in project TerraFirmaCraft by TerraFirmaCraft.

the class CropHelpers method growthTickStep.

public static boolean growthTickStep(Level level, BlockPos pos, BlockState state, Random random, long fromTick, long toTick, CropBlockEntity crop) {
    // Calculate invariants
    final ICalendar calendar = Calendars.get(level);
    final BlockPos sourcePos = pos.below();
    final int hydration = FarmlandBlock.getHydration(level, sourcePos);
    final float startTemperature = Climate.getTemperature(level, pos, calendar, Calendars.SERVER.ticksToCalendarTicks(fromTick));
    final float endTemperature = Climate.getTemperature(level, pos, calendar, Calendars.SERVER.ticksToCalendarTicks(toTick));
    final long tickDelta = toTick - fromTick;
    final ICropBlock cropBlock = (ICropBlock) state.getBlock();
    final ClimateRange range = cropBlock.getClimateRange();
    final boolean growing = checkClimate(range, hydration, startTemperature, endTemperature, false);
    final boolean healthy = growing || checkClimate(range, hydration, startTemperature, endTemperature, true);
    // Nutrients are consumed first, since they are independent of growth or health.
    // As long as the crop exists it consumes nutrients.
    final FarmlandBlockEntity farmland = level.getBlockEntity(sourcePos, TFCBlockEntities.FARMLAND.get()).orElse(null);
    final FarmlandBlockEntity.NutrientType primaryNutrient = cropBlock.getPrimaryNutrient();
    float nutrientsAvailable = 0, nutrientsRequired = NUTRIENT_CONSUMPTION * tickDelta, nutrientsConsumed = 0;
    if (farmland != null) {
        nutrientsAvailable = farmland.getNutrient(primaryNutrient);
        nutrientsConsumed = farmland.consumeNutrientAndResupplyOthers(primaryNutrient, nutrientsRequired);
    }
    // Total growth is based on the ticks and the nutrients consumed. It is then allocated to actual growth or expiry based on other factors.
    float totalGrowthDelta = Helpers.uniform(random, 0.9f, 1.1f) * tickDelta * GROWTH_FACTOR + nutrientsConsumed * NUTRIENT_GROWTH_FACTOR;
    final float initialGrowth = crop.getGrowth();
    float growth = initialGrowth, expiry = crop.getExpiry(), actualYield = crop.getYield();
    final float growthLimit = cropBlock.getGrowthLimit(level, pos, state);
    if (totalGrowthDelta > 0 && growing && growth < growthLimit) {
        // Allocate to growth
        final float delta = Math.min(totalGrowthDelta, growthLimit - growth);
        growth += delta;
        totalGrowthDelta -= delta;
    }
    if (totalGrowthDelta > 0) {
        // Allocate remaining growth to expiry
        final float delta = Math.min(totalGrowthDelta, EXPIRY_LIMIT - expiry);
        expiry += delta;
        totalGrowthDelta -= delta;
    }
    // Calculate yield, which depends both on a flat rate per growth, and on the nutrient satisfaction, which is a measure of nutrient consumption over the growth time.
    final float growthDelta = growth - initialGrowth;
    final float nutrientSatisfaction;
    if (growthDelta <= 0 || nutrientsRequired <= 0) {
        // Either condition causes the below formula to result in NaN
        nutrientSatisfaction = 1;
    } else {
        nutrientSatisfaction = Math.min(1, (totalGrowthDelta / growthDelta) * (nutrientsAvailable / nutrientsRequired));
    }
    actualYield += growthDelta * Helpers.lerp(nutrientSatisfaction, YIELD_MIN, YIELD_LIMIT);
    // Check if the crop should've expired.
    if (expiry >= EXPIRY_LIMIT || !healthy) {
        // Lenient here - instead of assuming it expired at the start of the duration, we assume at the end. Including growth during this period.
        cropBlock.die(level, pos, state, growth >= 1);
        return false;
    }
    crop.setGrowth(growth);
    crop.setYield(actualYield);
    crop.setExpiry(expiry);
    crop.setLastUpdateTick(calendar.getTicks());
    return true;
}
Also used : ClimateRange(net.dries007.tfc.util.climate.ClimateRange) FarmlandBlockEntity(net.dries007.tfc.common.blockentities.FarmlandBlockEntity) ICalendar(net.dries007.tfc.util.calendar.ICalendar) BlockPos(net.minecraft.core.BlockPos)

Example 5 with ClimateRange

use of net.dries007.tfc.util.climate.ClimateRange in project TerraFirmaCraft by TerraFirmaCraft.

the class CropBlock method addHoeOverlayInfo.

@Override
public void addHoeOverlayInfo(Level level, BlockPos pos, BlockState state, List<Component> text, boolean isDebug) {
    final ClimateRange range = climateRange.get();
    final BlockPos sourcePos = pos.below();
    text.add(FarmlandBlock.getHydrationTooltip(level, sourcePos, range, false));
    text.add(FarmlandBlock.getTemperatureTooltip(level, pos, range, false));
    level.getBlockEntity(pos, TFCBlockEntities.CROP.get()).ifPresent(crop -> {
        if (isDebug) {
            text.add(new TextComponent(String.format("[Debug] Growth = %.2f Yield = %.2f", crop.getGrowth(), crop.getYield())));
        }
        if (crop.getGrowth() >= 1) {
            text.add(new TranslatableComponent("tfc.tooltip.farmland.mature"));
        }
    });
}
Also used : TextComponent(net.minecraft.network.chat.TextComponent) ClimateRange(net.dries007.tfc.util.climate.ClimateRange) TranslatableComponent(net.minecraft.network.chat.TranslatableComponent) BlockPos(net.minecraft.core.BlockPos)

Aggregations

ClimateRange (net.dries007.tfc.util.climate.ClimateRange)7 BlockPos (net.minecraft.core.BlockPos)5 TranslatableComponent (net.minecraft.network.chat.TranslatableComponent)2 BlockState (net.minecraft.world.level.block.state.BlockState)2 FarmlandBlockEntity (net.dries007.tfc.common.blockentities.FarmlandBlockEntity)1 ICalendar (net.dries007.tfc.util.calendar.ICalendar)1 TextComponent (net.minecraft.network.chat.TextComponent)1