Search in sources :

Example 1 with Month

use of net.dries007.tfc.util.calendar.Month in project TerraFirmaCraft by TerraFirmaCraft.

the class StationaryBerryBushBlock method onUpdate.

@Override
public void onUpdate(Level level, BlockPos pos, BlockState state) {
    level.getBlockEntity(pos, TFCBlockEntities.BERRY_BUSH.get()).ifPresent(bush -> {
        Lifecycle currentLifecycle = state.getValue(LIFECYCLE);
        Lifecycle expectedLifecycle = getLifecycleForCurrentMonth();
        if (expectedLifecycle == Lifecycle.DORMANT) {
            // When we're in dormant time, no matter what conditions, or time since appearance, the bush will be dormant.
            if (expectedLifecycle != currentLifecycle) {
                level.setBlock(pos, state.setValue(LIFECYCLE, Lifecycle.DORMANT), 3);
            }
        } else {
            // Otherwise, we do a month-by-month evaluation of how the bush should have grown.
            // We only do this up to a year. Why? Because eventually, it will have become dormant, and any 'progress' during that year would've been lost anyway because it would unconditionally become dormant.
            long deltaTicks = Math.min(bush.getTicksSinceBushUpdate(), Calendars.SERVER.getCalendarTicksInYear());
            long currentCalendarTick = Calendars.SERVER.getCalendarTicks();
            long nextCalendarTick = currentCalendarTick - deltaTicks;
            final BlockPos sourcePos = pos.below();
            final ClimateRange range = climateRange.get();
            final int hydration = FarmlandBlock.getHydration(level, sourcePos);
            int stagesGrown = 0, monthsSpentDying = 0;
            do {
                // This always runs at least once. It is called through random ticks, and calendar updates - although calendar updates will only call this if they've waited at least a day, or the average delta between random ticks.
                // Otherwise it will just wait for the next random tick.
                // Jump forward to nextTick.
                // Advance both the stage (randomly, if the previous month was healthy), and lifecycle (if the at-the-time conditions were valid)
                nextCalendarTick = Math.min(nextCalendarTick + Calendars.SERVER.getCalendarTicksInMonth(), currentCalendarTick);
                if (currentLifecycle.active() && level.getRandom().nextInt(3) == 0) {
                    stagesGrown++;
                }
                float temperatureAtNextTick = Climate.getTemperature(level, pos, nextCalendarTick, Calendars.SERVER.getCalendarDaysInMonth());
                Lifecycle lifecycleAtNextTick = getLifecycleForMonth(ICalendar.getMonthOfYear(nextCalendarTick, Calendars.SERVER.getCalendarDaysInMonth()));
                if (range.checkBoth(hydration, temperatureAtNextTick, false)) {
                    currentLifecycle = currentLifecycle.advanceTowards(lifecycleAtNextTick);
                } else {
                    currentLifecycle = Lifecycle.DORMANT;
                }
                if (lifecycleAtNextTick != Lifecycle.DORMANT && currentLifecycle == Lifecycle.DORMANT) {
                    // consecutive months spent where the conditions were invalid, but they shouldn't've been
                    monthsSpentDying++;
                } else {
                    monthsSpentDying = 0;
                }
            } while (nextCalendarTick < currentCalendarTick);
            BlockState newState;
            if (monthsSpentDying > 0 && level.getRandom().nextInt(6) < monthsSpentDying) {
                // It may have died, as it spent too many consecutive months where it should've been healthy, in invalid conditions.
                newState = TFCBlocks.DEAD_BERRY_BUSH.get().defaultBlockState();
            } else {
                // It's not dead! Now, perform the actual update over the time taken.
                newState = state.setValue(STAGE, Math.min(2, state.getValue(STAGE) + stagesGrown)).setValue(LIFECYCLE, currentLifecycle);
                // Finally, possibly, cause a propagation event - this is based on the current time.
                if (newState.getValue(STAGE) == 2 && newState.getValue(LIFECYCLE).active() && level.getRandom().nextInt(3) == 0) {
                    propagate(level, pos, level.getRandom());
                }
            }
            // And update the block
            if (state != newState) {
                level.setBlock(pos, newState, 3);
            }
        }
        bush.afterUpdate();
    });
}
Also used : ClimateRange(net.dries007.tfc.util.climate.ClimateRange) BlockState(net.minecraft.world.level.block.state.BlockState) BlockPos(net.minecraft.core.BlockPos)

Example 2 with Month

use of net.dries007.tfc.util.calendar.Month in project TerraFirmaCraft by TerraFirmaCraft.

the class OverworldClimateModel method getTemperature.

@Override
public float getTemperature(@Nullable LevelReader level, BlockPos pos, ChunkData data, long calendarTicks, int daysInMonth) {
    // Month temperature
    final Month currentMonth = ICalendar.getMonthOfYear(calendarTicks, daysInMonth);
    final float delta = ICalendar.getFractionOfMonth(calendarTicks, daysInMonth);
    final float monthFactor = Mth.lerp(delta, currentMonth.getTemperatureModifier(), currentMonth.next().getTemperatureModifier());
    final float monthTemperature = calculateMonthlyTemperature(pos.getZ(), monthFactor);
    final float dailyTemperature = calculateDailyTemperature(calendarTicks);
    return adjustTemperatureByElevation(pos.getY(), data.getAverageTemp(pos), monthTemperature, dailyTemperature);
}
Also used : Month(net.dries007.tfc.util.calendar.Month)

Example 3 with Month

use of net.dries007.tfc.util.calendar.Month in project firmalife by eerussianguy.

the class ItemMetalMallet method onItemUse.

@Override
@Nonnull
@SuppressWarnings("deprecation")
public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
    if (!worldIn.isRemote && hand == EnumHand.MAIN_HAND) {
        Block block = worldIn.getBlockState(pos).getBlock();
        if (block instanceof BlockPlacedItemFlat) {
            TEPlacedItemFlat tile = (TEPlacedItemFlat) worldIn.getTileEntity(pos);
            if (tile == null)
                return EnumActionResult.FAIL;
            CrackingRecipe entry = CrackingRecipe.get(tile.getStack());
            if (entry == null)
                return EnumActionResult.FAIL;
            if (Constants.RNG.nextInt(100) < entry.getChance()) {
                InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), entry.getOutputItem(tile.getStack()));
                worldIn.playSound(null, pos, SoundEvents.BLOCK_WOOD_PLACE, SoundCategory.BLOCKS, 2.0F, 1.0F);
            } else
                worldIn.playSound(null, pos, SoundEvents.BLOCK_WOOD_FALL, SoundCategory.BLOCKS, 2.0F, 1.0F);
            tile.setStack(ItemStack.EMPTY);
            worldIn.setBlockToAir(pos);
            player.getHeldItem(hand).damageItem(1, player);
            return EnumActionResult.SUCCESS;
        } else if (block == BlocksFL.MELON_FRUIT) {
            List<ItemStack> drops = block.getDrops(worldIn, pos, worldIn.getBlockState(pos), 0);
            ItemStack stack = drops.get(0);
            if (stack.getItem() == Item.getItemFromBlock(block)) {
                IFood cap = stack.getCapability(CapabilityFood.CAPABILITY, null);
                if (cap != null) {
                    if (!cap.isRotten()) {
                        for (int i = 0; i < 2 + RNG.nextInt(4); i++) Helpers.spawnItemStack(worldIn, pos, new ItemStack(ItemsFL.getFood(FoodFL.MELON)));
                    }
                }
            }
            worldIn.destroyBlock(pos, false);
            worldIn.playSound(null, pos, SoundEvents.BLOCK_GRASS_BREAK, SoundCategory.BLOCKS, 1.0f, 1.0f);
            return EnumActionResult.SUCCESS;
        }
        BlockPos offsetPos;
        BlockPos logPos = pos;
        IBlockState logState = worldIn.getBlockState(pos);
        Block logBlock = logState.getBlock();
        // grabbing the registry to verify you're clicking a nut tree
        NutRecipe entry = NutRecipe.get(logBlock);
        if (entry == null)
            return EnumActionResult.FAIL;
        int leafCount = 0;
        for (int i = 1; i < 14; i++) {
            logPos = pos.up(i);
            logState = worldIn.getBlockState(logPos);
            if (// we already verified that logBlock is correct
            logState.getBlock() != logBlock)
                break;
            for (// this is a crappy leaf counting algorithm
            EnumFacing d : // this is a crappy leaf counting algorithm
            EnumFacing.HORIZONTALS) {
                IBlockState leafState;
                for (int j = 1; j < 5; j++) {
                    offsetPos = logPos.offset(d, j);
                    leafState = worldIn.getBlockState(offsetPos);
                    if (// offset the thing if the trunk seems to curve
                    j == 1 && leafState.getBlock() == logBlock)
                        pos = pos.offset(d, j);
                    if (worldIn.isAirBlock(offsetPos))
                        continue;
                    if (leafState.getBlock() == entry.getLeaves())
                        leafCount++;
                }
            }
        }
        if (leafCount > 0) {
            Month month = CalendarTFC.CALENDAR_TIME.getMonthOfYear();
            if (!(month == Month.OCTOBER || month == Month.NOVEMBER)) {
                player.sendStatusMessage(new TextComponentTranslation("tooltip.firmalife.not_fall"), true);
                return EnumActionResult.PASS;
            }
            IPlayerDataFL playerData = player.getCapability(CapPlayerDataFL.CAPABILITY, null);
            if (playerData != null) {
                boolean timePassed = (int) CalendarTFC.CALENDAR_TIME.getTicks() - playerData.getNuttedTime() > ConfigFL.General.BALANCE.nutTime;
                boolean distanced = playerData.getNutDistance(pos) > ConfigFL.General.BALANCE.nutDistance;
                if (distanced && timePassed) {
                    playerData.setNuttedTime();
                    playerData.setNutPosition(pos);
                    leafCount = (int) Math.ceil(leafCount * 0.66);
                    while (// batches drops a few times
                    leafCount > 0) {
                        int dropCount = Math.min(Constants.RNG.nextInt(4) + 1, leafCount);
                        BlockPos dropPos = logPos.offset(EnumFacing.random(Constants.RNG), Constants.RNG.nextInt(3) + 1);
                        // should be querying nut
                        Helpers.spawnItemStack(worldIn, dropPos, new ItemStack(entry.getNut().getItem(), Constants.RNG.nextInt(dropCount)));
                        TFCParticles.LEAF1.sendToAllNear(worldIn, dropPos.getX() + RNG.nextFloat() / 10, dropPos.getY() - RNG.nextFloat() / 10, dropPos.getZ() + RNG.nextFloat() / 10, (RNG.nextFloat() - 0.5) / 10, -0.15D + RNG.nextFloat() / 10, (RNG.nextFloat() - 0.5) / 10, 90);
                        leafCount -= dropCount;
                    }
                    worldIn.playSound(null, pos, SoundEvents.BLOCK_WOOD_PLACE, SoundCategory.BLOCKS, 3.0F, 1.0F);
                    player.getHeldItem(hand).damageItem(1, player);
                    player.addPotionEffect(new PotionEffect(MobEffects.HUNGER, 200, 1));
                } else {
                    if (!timePassed) {
                        player.sendStatusMessage(new TextComponentTranslation("tooltip.firmalife.refractory"), true);
                    } else {
                        player.sendStatusMessage(new TextComponentTranslation("tooltip.firmalife.distance"), true);
                    }
                    player.addPotionEffect(new PotionEffect(MobEffects.MINING_FATIGUE, 200, 1));
                    player.addPotionEffect(new PotionEffect(PotionEffectsTFC.THIRST, 200, 0));
                }
                return EnumActionResult.SUCCESS;
            }
        }
    }
    return EnumActionResult.FAIL;
}
Also used : CrackingRecipe(com.eerussianguy.firmalife.recipe.CrackingRecipe) IFood(net.dries007.tfc.api.capability.food.IFood) IPlayerDataFL(com.eerussianguy.firmalife.player.IPlayerDataFL) TextComponentTranslation(net.minecraft.util.text.TextComponentTranslation) IBlockState(net.minecraft.block.state.IBlockState) PotionEffect(net.minecraft.potion.PotionEffect) Month(net.dries007.tfc.util.calendar.Month) TEPlacedItemFlat(net.dries007.tfc.objects.te.TEPlacedItemFlat) Block(net.minecraft.block.Block) ItemBlock(net.minecraft.item.ItemBlock) List(java.util.List) BlockPos(net.minecraft.util.math.BlockPos) NutRecipe(com.eerussianguy.firmalife.recipe.NutRecipe) BlockPlacedItemFlat(net.dries007.tfc.objects.blocks.BlockPlacedItemFlat) ItemStack(net.minecraft.item.ItemStack) Nonnull(javax.annotation.Nonnull)

Aggregations

Month (net.dries007.tfc.util.calendar.Month)2 IPlayerDataFL (com.eerussianguy.firmalife.player.IPlayerDataFL)1 CrackingRecipe (com.eerussianguy.firmalife.recipe.CrackingRecipe)1 NutRecipe (com.eerussianguy.firmalife.recipe.NutRecipe)1 List (java.util.List)1 Nonnull (javax.annotation.Nonnull)1 IFood (net.dries007.tfc.api.capability.food.IFood)1 BlockPlacedItemFlat (net.dries007.tfc.objects.blocks.BlockPlacedItemFlat)1 TEPlacedItemFlat (net.dries007.tfc.objects.te.TEPlacedItemFlat)1 ClimateRange (net.dries007.tfc.util.climate.ClimateRange)1 Block (net.minecraft.block.Block)1 IBlockState (net.minecraft.block.state.IBlockState)1 BlockPos (net.minecraft.core.BlockPos)1 ItemBlock (net.minecraft.item.ItemBlock)1 ItemStack (net.minecraft.item.ItemStack)1 PotionEffect (net.minecraft.potion.PotionEffect)1 BlockPos (net.minecraft.util.math.BlockPos)1 TextComponentTranslation (net.minecraft.util.text.TextComponentTranslation)1 BlockState (net.minecraft.world.level.block.state.BlockState)1