diff --git a/gradle.properties b/gradle.properties index b8252f6..bd374b6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings = 1.19.2+build.28 mod_id = blossom mod_author = yurisuika -mod_version = 1.1.0 +mod_version = 2.0.0 maven_group = dev.yurisuika.blossom archives_base_name = blossom diff --git a/src/main/java/dev/yurisuika/blossom/Blossom.java b/src/main/java/dev/yurisuika/blossom/Blossom.java index c72bcfb..d473409 100644 --- a/src/main/java/dev/yurisuika/blossom/Blossom.java +++ b/src/main/java/dev/yurisuika/blossom/Blossom.java @@ -3,6 +3,11 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import dev.yurisuika.blossom.block.FloweringLeavesBlock; +import dev.yurisuika.blossom.block.FruitingLeavesBlock; +import dev.yurisuika.blossom.client.particle.BlossomParticle; +import dev.yurisuika.blossom.entity.ai.goal.BlossomGoal; +import dev.yurisuika.blossom.entity.ai.goal.FruitGoal; +import dev.yurisuika.blossom.mixin.block.BlocksInvoker; import dev.yurisuika.blossom.mixin.block.ComposterBlockInvoker; import dev.yurisuika.blossom.mixin.block.FireBlockInvoker; import dev.yurisuika.blossom.server.command.BlossomCommand; @@ -13,13 +18,20 @@ import net.minecraft.client.item.ModelPredicateProviderRegistry; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayers; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.BeeEntity; import net.minecraft.item.*; import net.minecraft.nbt.NbtCompound; +import net.minecraft.particle.DefaultParticleType; +import net.minecraft.particle.ParticleType; +import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RegisterColorHandlersEvent; +import net.minecraftforge.client.event.RegisterParticleProvidersEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -46,10 +58,9 @@ public class Blossom { public static class Config { public Value value = new Value( - new Value.Propagation(0.2F), - new Value.Fertilization(0.06666667F), - new Value.Pollination(1), - new Value.Fruit(3, 0.5714286F) + new Value.Blossoming(0.2F, 10.0D), + new Value.Fruiting(0.2F, 10.0D), + new Value.Harvesting(3, 0.5714286F) ); public Filter filter = new Filter( new Filter.Temperature(-2.0F, 2.0F), @@ -66,54 +77,46 @@ public static class Config { public static class Value { - public Propagation propagation; - public Fertilization fertilization; - public Pollination pollination; - public Fruit fruit; + public Blossoming blossoming; + public Fruiting fruiting; + public Harvesting harvesting; - public Value(Propagation propagation, Fertilization fertilization, Pollination pollination, Fruit fruit) { - this.propagation = propagation; - this.fertilization = fertilization; - this.pollination = pollination; - this.fruit = fruit; + public Value(Blossoming blossoming, Fruiting fruiting, Harvesting harvesting) { + this.blossoming = blossoming; + this.fruiting = fruiting; + this.harvesting = harvesting; } - public static class Propagation { + public static class Blossoming { public float chance; + public double distance; - public Propagation(float chance) { + public Blossoming(float chance, double distance) { this.chance = chance; + this.distance = distance; } } - public static class Fertilization { + public static class Fruiting { public float chance; + public double distance; - public Fertilization(float chance) { + public Fruiting(float chance, double distance) { this.chance = chance; + this.distance = distance; } } - public static class Pollination { - - public int age; - - public Pollination(int age) { - this.age = age; - } - - } - - public static class Fruit { + public static class Harvesting { public int bonus; public float chance; - public Fruit(int bonus, float chance) { + public Harvesting(int bonus, float chance) { this.bonus = bonus; this.chance = chance; } @@ -231,19 +234,20 @@ public static Config getConfig() { } public static void checkBounds() { - config.value.propagation.chance = Math.max(Math.min(config.value.propagation.chance, 1.0F), 0.0F); - config.value.fertilization.chance = Math.max(Math.min(config.value.fertilization.chance, 1.0F), 0.0F); - config.value.pollination.age = Math.max(Math.min(config.value.pollination.age, 7), 0); - config.value.fruit.bonus = Math.max(config.value.fruit.bonus, 0); - config.value.fruit.chance = Math.max(Math.min(config.value.fruit.chance, 1.0F), 0.0F); + config.value.blossoming.chance = Math.max(Math.min(config.value.blossoming.chance, 1.0F), 0.0F); + config.value.blossoming.distance = Math.max(config.value.blossoming.distance, 0.0D); + config.value.fruiting.chance = Math.max(Math.min(config.value.fruiting.chance, 1.0F), 0.0F); + config.value.fruiting.distance = Math.max(config.value.fruiting.distance, 0.0D); + config.value.harvesting.bonus = Math.max(config.value.harvesting.bonus, 0); + config.value.harvesting.chance = Math.max(Math.min(config.value.harvesting.chance, 1.0F), 0.0F); float temperatureMin = Math.max(Math.min(Math.min(config.filter.temperature.min, 2.0F), config.filter.temperature.max), -2.0F); float temperatureMax = Math.max(Math.max(Math.min(config.filter.temperature.max, 2.0F), config.filter.temperature.min), -2.0F); config.filter.temperature.min = temperatureMin; config.filter.temperature.max = temperatureMax; - float downfallMin = Math.max(Math.min(Math.min(config.filter.downfall.min, 2.0F), config.filter.downfall.max), -2.0F); - float downfallMax = Math.max(Math.max(Math.min(config.filter.downfall.max, 2.0F), config.filter.downfall.min), -2.0F); + float downfallMin = Math.max(Math.min(Math.min(config.filter.downfall.min, 1.0F), config.filter.downfall.max), 0.0F); + float downfallMax = Math.max(Math.max(Math.min(config.filter.downfall.max, 1.0F), config.filter.downfall.min), 0.0F); config.filter.downfall.min = downfallMin; config.filter.downfall.max = downfallMax; @@ -257,8 +261,26 @@ public static void checkBounds() { public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, "blossom"); public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, "blossom"); - - public static final RegistryObject FLOWERING_OAK_LEAVES = register("flowering_oak_leaves", () -> new FloweringLeavesBlock(Blocks.OAK_LEAVES, Items.APPLE, AbstractBlock.Settings.copy(Blocks.OAK_LEAVES)), new Item.Settings()); + public static final DeferredRegister> PARTICLES = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, "blossom"); + + public static final RegistryObject FRUITING_OAK_LEAVES = register("fruiting_oak_leaves", () -> new FruitingLeavesBlock(Blocks.OAK_LEAVES, Items.APPLE, AbstractBlock.Settings.of(Material.LEAVES) + .strength(0.2f) + .ticksRandomly() + .sounds(BlockSoundGroup.GRASS) + .nonOpaque() + .allowsSpawning(BlocksInvoker::invokeCanSpawnOnLeaves) + .suffocates(BlocksInvoker::invokeNever) + .blockVision(BlocksInvoker::invokeNever)), new Item.Settings()); + public static final RegistryObject FLOWERING_OAK_LEAVES = register("flowering_oak_leaves", () -> new FloweringLeavesBlock(Blocks.OAK_LEAVES, Blossom.FRUITING_OAK_LEAVES.get(), AbstractBlock.Settings.of(Material.LEAVES) + .strength(0.2f) + .ticksRandomly() + .sounds(BlockSoundGroup.GRASS) + .nonOpaque() + .allowsSpawning(BlocksInvoker::invokeCanSpawnOnLeaves) + .suffocates(BlocksInvoker::invokeNever) + .blockVision(BlocksInvoker::invokeNever)), new Item.Settings()); + + public static RegistryObject BLOSSOM = PARTICLES.register("blossom", () -> new DefaultParticleType(false)); public static RegistryObject register(String name, Supplier supplier, Item.Settings settings) { RegistryObject block = BLOCKS.register(name, supplier); @@ -270,10 +292,19 @@ public static RegistryObject register(String name, Supplier public static class CommonForgeEvents { @SubscribeEvent - public static void registerCommands(RegisterCommandsEvent event) { + public static void registerCommandsEvents(RegisterCommandsEvent event) { BlossomCommand.register(event.getDispatcher(), event.getBuildContext(), event.getCommandSelection()); } + @SubscribeEvent + public static void entityJoinLevelEvents(EntityJoinLevelEvent event) { + Entity entity = event.getEntity(); + if (entity instanceof BeeEntity) { + ((BeeEntity)entity).getGoalSelector().add(4, new BlossomGoal((BeeEntity)entity)); + ((BeeEntity)entity).getGoalSelector().add(4, new FruitGoal((BeeEntity)entity)); + } + } + } @Mod.EventBusSubscriber(modid = "blossom", bus = Mod.EventBusSubscriber.Bus.MOD) @@ -282,8 +313,15 @@ public static class CommonModBusEvents { @SubscribeEvent public static void commonSetup(FMLCommonSetupEvent event) { ComposterBlockInvoker.invokeRegisterComposableItem(0.3F, Blossom.FLOWERING_OAK_LEAVES.get()); + ComposterBlockInvoker.invokeRegisterComposableItem(0.3F, Blossom.FRUITING_OAK_LEAVES.get()); ((FireBlockInvoker)Blocks.FIRE).invokeRegisterFlammableBlock(Blossom.FLOWERING_OAK_LEAVES.get(), 30, 60); + ((FireBlockInvoker) Blocks.FIRE).invokeRegisterFlammableBlock(Blossom.FRUITING_OAK_LEAVES.get(), 30, 60); + } + + @SubscribeEvent + public static void registerParticleProvidersEvents(RegisterParticleProvidersEvent event) { + MinecraftClient.getInstance().particleManager.registerFactory(BLOSSOM.get(), BlossomParticle.Factory::new); } } @@ -295,8 +333,18 @@ public static class ClientModBusEvents { @SubscribeEvent public static void clientSetup(FMLClientSetupEvent event) { RenderLayers.setRenderLayer(Blossom.FLOWERING_OAK_LEAVES.get(), RenderLayer.getCutout()); + RenderLayers.setRenderLayer(Blossom.FRUITING_OAK_LEAVES.get(), RenderLayer.getCutout()); ModelPredicateProviderRegistry.register(FLOWERING_OAK_LEAVES.get().asItem(), new Identifier("age"), (stack, world, entity, seed) -> { + NbtCompound nbtCompound = stack.getSubNbt("BlockStateTag"); + try { + if (nbtCompound != null && nbtCompound.get(FloweringLeavesBlock.AGE.getName()) != null) { + return (float)Integer.parseInt(nbtCompound.get(FloweringLeavesBlock.AGE.getName()).asString()) / 4.0F; + } + } catch (NumberFormatException ignored) {} + return 0.0F; + }); + ModelPredicateProviderRegistry.register(FRUITING_OAK_LEAVES.get().asItem(), new Identifier("age"), (stack, world, entity, seed) -> { NbtCompound nbtCompound = stack.getSubNbt("BlockStateTag"); try { if (nbtCompound != null && nbtCompound.get(FloweringLeavesBlock.AGE.getName()) != null) { @@ -308,13 +356,15 @@ public static void clientSetup(FMLClientSetupEvent event) { } @SubscribeEvent - public static void registerBlockColorProviders(final RegisterColorHandlersEvent.Block color) { - color.getBlockColors().registerColorProvider((state, world, pos, tintIndex) -> world != null && pos != null ? BiomeColors.getFoliageColor(world, pos) : FoliageColors.getColor(0.5, 1.0), Blossom.FLOWERING_OAK_LEAVES.get()); + public static void registerBlockColorHandlersEvents(RegisterColorHandlersEvent.Block event) { + event.getBlockColors().registerColorProvider((state, world, pos, tintIndex) -> world != null && pos != null ? BiomeColors.getFoliageColor(world, pos) : FoliageColors.getColor(0.5, 1.0), Blossom.FLOWERING_OAK_LEAVES.get()); + event.getBlockColors().registerColorProvider((state, world, pos, tintIndex) -> world != null && pos != null ? BiomeColors.getFoliageColor(world, pos) : FoliageColors.getColor(0.5, 1.0), Blossom.FRUITING_OAK_LEAVES.get()); } @SubscribeEvent - public static void registerItemColorProviders(final RegisterColorHandlersEvent.Item color) { - color.getItemColors().register((stack, tintIndex) -> tintIndex > 0 ? -1 : MinecraftClient.getInstance().getBlockColors().getColor(((BlockItem) stack.getItem()).getBlock().getDefaultState(), null, null, tintIndex), FLOWERING_OAK_LEAVES.get()); + public static void registerItemColorHandlersEvents(RegisterColorHandlersEvent.Item event) { + event.getItemColors().register((stack, tintIndex) -> tintIndex > 0 ? -1 : MinecraftClient.getInstance().getBlockColors().getColor(((BlockItem) stack.getItem()).getBlock().getDefaultState(), null, null, tintIndex), FLOWERING_OAK_LEAVES.get()); + event.getItemColors().register((stack, tintIndex) -> tintIndex > 0 ? -1 : MinecraftClient.getInstance().getBlockColors().getColor(((BlockItem) stack.getItem()).getBlock().getDefaultState(), null, null, tintIndex), FRUITING_OAK_LEAVES.get()); } } @@ -329,6 +379,7 @@ public Blossom() { BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus()); ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus()); + PARTICLES.register(FMLJavaModLoadingContext.get().getModEventBus()); } } \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/block/FloweringLeavesBlock.java b/src/main/java/dev/yurisuika/blossom/block/FloweringLeavesBlock.java index ee91142..94956d7 100644 --- a/src/main/java/dev/yurisuika/blossom/block/FloweringLeavesBlock.java +++ b/src/main/java/dev/yurisuika/blossom/block/FloweringLeavesBlock.java @@ -1,14 +1,16 @@ package dev.yurisuika.blossom.block; -import dev.yurisuika.blossom.mixin.world.biome.BiomeAccessor; -import net.minecraft.block.*; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.enchantment.Enchantments; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Fertilizable; +import net.minecraft.block.LeavesBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.FluidState; import net.minecraft.fluid.Fluids; -import net.minecraft.item.*; -import net.minecraft.particle.ParticleTypes; +import net.minecraft.item.Item; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ShearsItem; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; @@ -22,8 +24,8 @@ import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; @@ -35,25 +37,25 @@ import net.minecraft.world.event.GameEvent; import java.util.OptionalInt; -import java.util.concurrent.ThreadLocalRandom; import static dev.yurisuika.blossom.Blossom.*; -public class FloweringLeavesBlock extends Block implements Fertilizable { +public class FloweringLeavesBlock extends LeavesBlock implements Fertilizable { public final Block shearedBlock; - public final Item shearedItem; + public final Block pollinatedBlock; public static final IntProperty DISTANCE = Properties.DISTANCE_1_7; public static final BooleanProperty PERSISTENT = Properties.PERSISTENT; public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; - public static final IntProperty AGE = Properties.AGE_7; + public static final IntProperty AGE = Properties.AGE_3; + public static final IntProperty RIPENESS = IntProperty.of("ripeness", 0, 7); - public FloweringLeavesBlock(Block shearedBlock, Item shearedItem, Settings settings) { + public FloweringLeavesBlock(Block shearedBlock, Block pollinatedBlock, Settings settings) { super(settings); this.shearedBlock = shearedBlock; - this.shearedItem = shearedItem; - this.setDefaultState(this.stateManager.getDefaultState().with(DISTANCE, 1).with(PERSISTENT, false).with(WATERLOGGED, false).with(AGE, 0)); + this.pollinatedBlock = pollinatedBlock; + setDefaultState(stateManager.getDefaultState().with(DISTANCE, 1).with(PERSISTENT, false).with(WATERLOGGED, false).with(AGE, 0).with(RIPENESS, 0)); } public VoxelShape getSidesShape(BlockState state, BlockView world, BlockPos pos) { @@ -61,7 +63,7 @@ public VoxelShape getSidesShape(BlockState state, BlockView world, BlockPos pos) } public boolean hasRandomTicks(BlockState state) { - return state.get(DISTANCE) == 7 || !this.isMature(state) || state.get(WATERLOGGED); + return true; } public IntProperty getAgeProperty() { @@ -69,19 +71,31 @@ public IntProperty getAgeProperty() { } public int getMaxAge() { - return 7; + return 3; } public int getAge(BlockState state) { - return state.get(this.getAgeProperty()); + return state.get(getAgeProperty()); } - public BlockState withAge(BlockState state, int age) { - return state.with(this.getAgeProperty(), age); + public boolean isMature(BlockState state) { + return state.get(getAgeProperty()) >= getMaxAge(); } - public boolean isMature(BlockState state) { - return state.get(this.getAgeProperty()) >= this.getMaxAge(); + public IntProperty getRipenessProperty() { + return RIPENESS; + } + + public int getMaxRipeness() { + return 7; + } + + public int getRipeness(BlockState state) { + return state.get(getRipenessProperty()); + } + + public boolean isRipe(BlockState state) { + return state.get(getRipenessProperty()) >= getMaxRipeness(); } public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { @@ -94,11 +108,11 @@ public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random .with(PERSISTENT, state.get(PERSISTENT)) .with(WATERLOGGED, state.get(WATERLOGGED)) ); - } else if (!this.isMature(state) && world.getBaseLightLevel(pos, 0) >= 9) { - int i = this.getAge(state); - if (i < this.getMaxAge()) { + } else if (!isMature(state) && world.getBaseLightLevel(pos, 0) >= 9) { + int i = getAge(state); + if (i < getMaxAge()) { float temperature = world.getBiome(pos).value().getTemperature(); - float downfall = ((BiomeAccessor)(Object)world.getBiome(pos).value()).getWeather().downfall(); + float downfall = world.getBiome(pos).value().getDownfall(); temperature += 2; float f = (downfall * temperature) / 4; f = ((4 - 1) * f) + 1; @@ -107,10 +121,31 @@ public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random f = 5.0F; } if (random.nextInt((int)(25.0F / f) + 1) == 0) { - world.setBlockState(pos, state.with(AGE, i + 1), 2); + world.setBlockState(pos, getDefaultState().with(AGE, i + 1) + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + .with(RIPENESS, state.get(RIPENESS)), 2); + } + } + } else if (isMature(state)) { + int i = getRipeness(state); + if (i < getMaxRipeness()) { + if (random.nextInt((int)(25.0F) + 1) == 0) { + world.setBlockState(pos, getDefaultState().with(RIPENESS, i + 1), 2); } } } + if (isRipe(state)) { + world.setBlockState(pos, shearedBlock.getDefaultState() + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + ); + } + if (!isMature(state) && state.get(RIPENESS) > 0) { + world.setBlockState(pos, getDefaultState().with(RIPENESS, 0), 2); + } } public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { @@ -118,12 +153,16 @@ public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Ran } public void applyGrowth(World world, BlockPos pos, BlockState state) { - int i = this.getAge(state) + this.getGrowthAmount(world); - int j = this.getMaxAge(); + int i = getAge(state) + getGrowthAmount(world); + int j = getMaxAge(); if (i > j) { i = j; } - world.setBlockState(pos, state.with(AGE, i), 2); + world.setBlockState(pos, getDefaultState().with(AGE, i) + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + .with(RIPENESS, state.get(RIPENESS)), 2); } public int getGrowthAmount(World world) { @@ -177,31 +216,29 @@ public FluidState getFluidState(BlockState state) { } public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { - if (world.hasRain(pos.up())) { - if (random.nextInt(15) == 1) { - BlockPos blockPos = pos.down(); - BlockState blockState = world.getBlockState(blockPos); - if (!blockState.isOpaque() || !blockState.isSideSolidFullSquare(world, blockPos, Direction.UP)) { - double d = (double)pos.getX() + random.nextDouble(); - double e = (double)pos.getY() - 0.05D; - double f = (double)pos.getZ() + random.nextDouble(); - world.addParticle(ParticleTypes.DRIPPING_WATER, d, e, f, 0.0D, 0.0D, 0.0D); - } - } + super.randomDisplayTick(state, world, pos, random); + if (random.nextInt(10) != 0) { + return; + } + if (FloweringLeavesBlock.isFaceFullSquare(world.getBlockState(pos.down()).getCollisionShape(world, pos.down()), Direction.UP)) { + return; } + double d = (double)pos.getX() + random.nextDouble(); + double e = (double)pos.getY() - 0.05; + double f = (double)pos.getZ() + random.nextDouble(); + world.addParticle(BLOSSOM.get(), d, e, f, 0.0, 0.0, 0.0); } public void appendProperties(Builder builder) { - builder.add(DISTANCE, PERSISTENT, WATERLOGGED, AGE); + builder.add(DISTANCE, PERSISTENT, WATERLOGGED, AGE, RIPENESS); } public BlockState getPlacementState(ItemPlacementContext ctx) { - return updateDistanceFromLogs(this.getDefaultState().with(PERSISTENT, true).with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER).with(AGE, 0), ctx.getWorld(), ctx.getBlockPos()); + return updateDistanceFromLogs(getDefaultState().with(PERSISTENT, true).with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER).with(AGE, 0).with(RIPENESS, 0), ctx.getWorld(), ctx.getBlockPos()); } - @Override public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) { - return !this.isMature(state); + return !isMature(state); } public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) { @@ -209,39 +246,26 @@ public boolean canGrow(World world, Random random, BlockPos pos, BlockState stat } public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) { - this.applyGrowth(world, pos, state); - } - - public static void dropFruit(World world, BlockPos pos, Item item, int bonus) { - int count = 1; - for(int i = 0; i < config.value.fruit.bonus + bonus; i++) { - if (ThreadLocalRandom.current().nextFloat() <= config.value.fruit.chance) { - count++; - } - } - dropStack(world, pos, new ItemStack(item, count)); + applyGrowth(world, pos, state); } public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { ItemStack itemStack = player.getStackInHand(hand); - if (state.get(AGE) == 7) { - Item item = itemStack.getItem(); - if (item instanceof ShearsItem) { - world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_CROP_BREAK, SoundCategory.NEUTRAL, 1.0F, 1.0F); - dropFruit(world, pos, this.shearedItem, (itemStack.hasEnchantments() && EnchantmentHelper.get(itemStack).containsKey(Enchantments.FORTUNE)) ? EnchantmentHelper.getLevel(Enchantments.FORTUNE, itemStack) : 0); - itemStack.damage(1, player, (entity) -> { - entity.sendToolBreakStatus(hand); - }); - if (!world.isClient()) { - player.incrementStat(Stats.USED.getOrCreateStat(item)); - } - world.emitGameEvent(player, GameEvent.SHEAR, pos); - world.setBlockState(pos, this.shearedBlock.getDefaultState() - .with(DISTANCE, state.get(DISTANCE)) - .with(PERSISTENT, state.get(PERSISTENT)) - .with(WATERLOGGED, state.get(WATERLOGGED)) - ); + Item item = itemStack.getItem(); + if (item instanceof ShearsItem) { + world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_CROP_BREAK, SoundCategory.NEUTRAL, 1.0F, 1.0F); + itemStack.damage(1, player, (entity) -> { + entity.sendToolBreakStatus(hand); + }); + if (!world.isClient()) { + player.incrementStat(Stats.USED.getOrCreateStat(item)); } + world.emitGameEvent(player, GameEvent.SHEAR, pos); + world.setBlockState(pos, shearedBlock.getDefaultState() + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + ); return ActionResult.SUCCESS; } else { return ActionResult.PASS; diff --git a/src/main/java/dev/yurisuika/blossom/block/FruitingLeavesBlock.java b/src/main/java/dev/yurisuika/blossom/block/FruitingLeavesBlock.java new file mode 100644 index 0000000..daa9a3c --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/block/FruitingLeavesBlock.java @@ -0,0 +1,282 @@ +package dev.yurisuika.blossom.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Fertilizable; +import net.minecraft.block.LeavesBlock; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.Item; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ShearsItem; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.stat.Stats; +import net.minecraft.state.StateManager.Builder; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.IntProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.tag.BlockTags; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.random.Random; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.event.GameEvent; + +import java.util.OptionalInt; +import java.util.concurrent.ThreadLocalRandom; + +import static dev.yurisuika.blossom.Blossom.*; + +public class FruitingLeavesBlock extends LeavesBlock implements Fertilizable { + + public final Block shearedBlock; + public final Item shearedItem; + + public static final IntProperty DISTANCE = Properties.DISTANCE_1_7; + public static final BooleanProperty PERSISTENT = Properties.PERSISTENT; + public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; + public static final IntProperty AGE = Properties.AGE_7; + public static final IntProperty RIPENESS = IntProperty.of("ripeness", 0, 7); + + public FruitingLeavesBlock(Block shearedBlock, Item shearedItem, Settings settings) { + super(settings); + this.shearedBlock = shearedBlock; + this.shearedItem = shearedItem; + setDefaultState(stateManager.getDefaultState().with(DISTANCE, 1).with(PERSISTENT, false).with(WATERLOGGED, false).with(AGE, 0).with(RIPENESS, 0)); + } + + public VoxelShape getSidesShape(BlockState state, BlockView world, BlockPos pos) { + return VoxelShapes.empty(); + } + + public boolean hasRandomTicks(BlockState state) { + return true; + } + + public IntProperty getAgeProperty() { + return AGE; + } + + public int getMaxAge() { + return 7; + } + + public int getAge(BlockState state) { + return state.get(getAgeProperty()); + } + + public boolean isMature(BlockState state) { + return state.get(getAgeProperty()) >= getMaxAge(); + } + + public IntProperty getRipenessProperty() { + return RIPENESS; + } + + public int getMaxRipeness() { + return 7; + } + + public int getRipeness(BlockState state) { + return state.get(getRipenessProperty()); + } + + public boolean isRipe(BlockState state) { + return state.get(getRipenessProperty()) >= getMaxRipeness(); + } + + public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (!(Boolean)state.get(PERSISTENT) && state.get(DISTANCE) == 7) { + dropStacks(state, world, pos); + world.removeBlock(pos, false); + } else if (state.get(WATERLOGGED)) { + world.setBlockState(pos, shearedBlock.getDefaultState() + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + ); + } else if (!isMature(state) && world.getBaseLightLevel(pos, 0) >= 9) { + int i = getAge(state); + if (i < getMaxAge()) { + float temperature = world.getBiome(pos).value().getTemperature(); + float downfall = world.getBiome(pos).value().getDownfall(); + temperature += 2; + float f = (downfall * temperature) / 4; + f = ((4 - 1) * f) + 1; + Biome.Precipitation precipitation = world.getBiome(pos).value().getPrecipitation(); + if (world.isRaining() && precipitation == Biome.Precipitation.RAIN) { + f = 5.0F; + } + if (random.nextInt((int)(25.0F / f) + 1) == 0) { + world.setBlockState(pos, getDefaultState().with(AGE, i + 1) + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + .with(RIPENESS, state.get(RIPENESS)), 2); + } + } + } else if (isMature(state)) { + int i = getRipeness(state); + if (i < getMaxRipeness()) { + if (random.nextInt((int)(25.0F) + 1) == 0) { + world.setBlockState(pos, getDefaultState().with(RIPENESS, i + 1), 2); + } + } + } + if (isRipe(state)) { + dropFruit(world, pos, shearedItem, 0); + world.setBlockState(pos, shearedBlock.getDefaultState() + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + ); + } + if (!isMature(state) && state.get(RIPENESS) > 0) { + world.setBlockState(pos, getDefaultState().with(RIPENESS, 0), 2); + } + } + + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + world.setBlockState(pos, updateDistanceFromLogs(state, world, pos), 3); + } + + public void applyGrowth(World world, BlockPos pos, BlockState state) { + int i = getAge(state) + getGrowthAmount(world); + int j = getMaxAge(); + if (i > j) { + i = j; + } + world.setBlockState(pos, getDefaultState().with(AGE, i) + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + .with(RIPENESS, state.get(RIPENESS)), 2); + } + + public int getGrowthAmount(World world) { + return MathHelper.nextInt(world.random, 2, 5); + } + + public int getOpacity(BlockState state, BlockView world, BlockPos pos) { + return 1; + } + + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + if (state.get(WATERLOGGED)) { + world.createAndScheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + } + int i = getDistanceFromLog(neighborState) + 1; + if (i != 1 || state.get(DISTANCE) != i) { + world.createAndScheduleBlockTick(pos, this, 1); + } + return state; + } + + public static BlockState updateDistanceFromLogs(BlockState state, WorldAccess world, BlockPos pos) { + int i = 7; + Mutable mutable = new Mutable(); + for (Direction direction : Direction.values()) { + mutable.set(pos, direction); + i = Math.min(i, getDistanceFromLog(world.getBlockState(mutable)) + 1); + if (i == 1) { + break; + } + } + return state.with(DISTANCE, i); + } + + public static int getDistanceFromLog(BlockState state) { + return getOptionalDistanceFromLog(state).orElse(7); + } + + public static OptionalInt getOptionalDistanceFromLog(BlockState state) { + if (state.isIn(BlockTags.LOGS)) { + return OptionalInt.of(0); + } + if (state.contains(DISTANCE)) { + return OptionalInt.of(state.get(DISTANCE)); + } + return OptionalInt.empty(); + } + + public FluidState getFluidState(BlockState state) { + return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state); + } + + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + super.randomDisplayTick(state, world, pos, random); + } + + public void appendProperties(Builder builder) { + builder.add(DISTANCE, PERSISTENT, WATERLOGGED, AGE, RIPENESS); + } + + public BlockState getPlacementState(ItemPlacementContext ctx) { + return updateDistanceFromLogs(getDefaultState().with(PERSISTENT, true).with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER).with(AGE, 0).with(RIPENESS, 0), ctx.getWorld(), ctx.getBlockPos()); + } + + public boolean isFertilizable(BlockView world, BlockPos pos, BlockState state, boolean isClient) { + return !isMature(state); + } + + public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) { + return true; + } + + public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) { + applyGrowth(world, pos, state); + } + + public static void dropFruit(World world, BlockPos pos, Item item, int bonus) { + int count = 1; + for(int i = 0; i < config.value.harvesting.bonus + bonus; i++) { + if (ThreadLocalRandom.current().nextFloat() <= config.value.harvesting.chance) { + count++; + } + } + dropStack(world, pos, new ItemStack(item, count)); + } + + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + ItemStack itemStack = player.getStackInHand(hand); + if (isMature(state)) { + Item item = itemStack.getItem(); + if (item instanceof ShearsItem) { + world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_CROP_BREAK, SoundCategory.NEUTRAL, 1.0F, 1.0F); + dropFruit(world, pos, shearedItem, (itemStack.hasEnchantments() && EnchantmentHelper.get(itemStack).containsKey(Enchantments.FORTUNE)) ? EnchantmentHelper.getLevel(Enchantments.FORTUNE, itemStack) : 0); + itemStack.damage(1, player, (entity) -> { + entity.sendToolBreakStatus(hand); + }); + if (!world.isClient()) { + player.incrementStat(Stats.USED.getOrCreateStat(item)); + } + world.emitGameEvent(player, GameEvent.SHEAR, pos); + world.setBlockState(pos, shearedBlock.getDefaultState() + .with(DISTANCE, state.get(DISTANCE)) + .with(PERSISTENT, state.get(PERSISTENT)) + .with(WATERLOGGED, state.get(WATERLOGGED)) + ); + } + return ActionResult.SUCCESS; + } else { + return ActionResult.PASS; + } + } + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/client/particle/BlossomParticle.java b/src/main/java/dev/yurisuika/blossom/client/particle/BlossomParticle.java new file mode 100644 index 0000000..c7a68c5 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/client/particle/BlossomParticle.java @@ -0,0 +1,71 @@ +package dev.yurisuika.blossom.client.particle; + +import net.minecraft.client.particle.*; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.particle.DefaultParticleType; + +public class BlossomParticle extends SpriteBillboardParticle { + + public float wind; + public final float drift; + public final float gust; + + public BlossomParticle(ClientWorld world, double x, double y, double z, SpriteProvider spriteProvider) { + super(world, x, y, z); + float f; + this.setSprite(spriteProvider.getSprite(random.nextInt(12), 12)); + this.wind = (float)Math.toRadians(random.nextBoolean() ? -30.0F : 30.0F); + this.drift = random.nextFloat(); + this.gust = (float)Math.toRadians(random.nextBoolean() ? -5.0F : 5.0F); + this.maxAge = 300; + this.gravityStrength = 7.5E-4F; + this.scale = f = random.nextBoolean() ? 0.05F : 0.075F; + this.setBoundingBoxSpacing(f, f); + this.velocityMultiplier = 1.0F; + } + + public ParticleTextureSheet getType() { + return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE; + } + + public record Factory(SpriteProvider spriteProvider) implements ParticleFactory { + + public Particle createParticle(DefaultParticleType parameters, ClientWorld world, double x, double y, double z, double r, double g, double b) { + return new BlossomParticle(world, x, y, z, spriteProvider); + } + + } + + public void tick() { + prevPosX = x; + prevPosY = y; + prevPosZ = z; + if (maxAge-- <= 0) { + markDead(); + } + if (dead) { + return; + } + float f = 300 - maxAge; + float g = Math.min(f / 300.0F, 1.0F); + double d = Math.cos(Math.toRadians(drift * 60.0F)) * 2.0D * Math.pow(g, 1.25D); + double e = Math.sin(Math.toRadians(drift * 60.0F)) * 2.0D * Math.pow(g, 1.25D); + velocityX += d * (double)0.0025F; + velocityZ += e * (double)0.0025F; + velocityY -= gravityStrength; + wind += gust / 20.0F; + prevAngle = angle; + angle += wind / 20.0F; + move(velocityX, velocityY, velocityZ); + if (onGround || maxAge < 299 && (velocityX == 0.0D || velocityZ == 0.0D)) { + markDead(); + } + if (dead) { + return; + } + velocityX *= velocityMultiplier; + velocityY *= velocityMultiplier; + velocityZ *= velocityMultiplier; + } + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/entity/ai/goal/BlossomGoal.java b/src/main/java/dev/yurisuika/blossom/entity/ai/goal/BlossomGoal.java new file mode 100644 index 0000000..3f24899 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/entity/ai/goal/BlossomGoal.java @@ -0,0 +1,313 @@ +package dev.yurisuika.blossom.entity.ai.goal; + +import dev.yurisuika.blossom.mixin.entity.EntityAccessor; +import dev.yurisuika.blossom.mixin.entity.MobEntityAccessor; +import dev.yurisuika.blossom.mixin.entity.passive.BeeEntityAccessor; +import dev.yurisuika.blossom.mixin.entity.passive.BeeEntityInvoker; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.ai.goal.Goal; +import net.minecraft.entity.passive.BeeEntity; +import net.minecraft.sound.SoundEvents; +import net.minecraft.state.property.Properties; +import net.minecraft.tag.TagKey; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.registry.RegistryEntry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.dimension.DimensionType; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Predicate; + +import static dev.yurisuika.blossom.Blossom.*; +import static net.minecraft.block.LeavesBlock.*; + +public class BlossomGoal extends Goal { + + public final BeeEntity entity; + public final Predicate targetPredicate = (state) -> { + if (state.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) { + return false; + } else { + return state.isOf(Blocks.OAK_LEAVES); + } + }; + public int blossomingTicks; + public int lastBlossomingTick; + public boolean running; + public Vec3d nextTarget; + public int ticks; + + public BlossomGoal(BeeEntity beeEntity) { + super(); + this.entity = beeEntity; + this.setControls(EnumSet.of(Control.MOVE)); + } + + public boolean checkFilters() { + RegistryEntry dimension = entity.getWorld().getDimensionEntry(); + RegistryEntry biome = entity.getWorld().getBiome(entity.getBlockPos()); + float temperature = biome.value().getTemperature(); + float downfall = biome.value().getDownfall(); + + AtomicBoolean whitelist = new AtomicBoolean(false); + if (config.toggle.whitelist) { + Arrays.stream(config.filter.dimension.whitelist).forEach(entry -> { + if (entry.startsWith("#")) { + TagKey tag = TagKey.of(Registry.DIMENSION_TYPE_KEY, new Identifier(entry.substring(1))); + if (tag != null) { + if (dimension.isIn(tag)) { + whitelist.set(true); + } + } + } else if (Objects.equals(entry, dimension.getKey().get().getValue().toString())) { + whitelist.set(true); + } + }); + Arrays.stream(config.filter.biome.whitelist).forEach(entry -> { + if (entry.startsWith("#")) { + TagKey tag = TagKey.of(Registry.BIOME_KEY, new Identifier(entry.substring(1))); + if (tag != null) { + if (biome.isIn(tag)) { + whitelist.set(true); + } + } + } else if (Objects.equals(entry, biome.getKey().get().getValue().toString())) { + whitelist.set(true); + } + }); + } + + AtomicBoolean blacklist = new AtomicBoolean(true); + if (config.toggle.blacklist) { + Arrays.stream(config.filter.dimension.blacklist).forEach(entry -> { + if (entry.startsWith("#")) { + TagKey tag = TagKey.of(Registry.DIMENSION_TYPE_KEY, new Identifier(entry.substring(1))); + if (tag != null) { + if (dimension.isIn(tag)) { + blacklist.set(false); + } + } + } else if (Objects.equals(entry, dimension.getKey().get().getValue().toString())) { + blacklist.set(false); + } + }); + Arrays.stream(config.filter.biome.blacklist).forEach(entry -> { + if (entry.startsWith("#")) { + TagKey tag = TagKey.of(Registry.BIOME_KEY, new Identifier(entry.substring(1))); + if (tag != null) { + if (biome.isIn(tag)) { + blacklist.set(false); + } + } + } else if (Objects.equals(entry, biome.getKey().get().getValue().toString())) { + blacklist.set(false); + } + }); + } + + if (temperature >= config.filter.temperature.min && temperature <= config.filter.temperature.max) { + if (downfall >= config.filter.downfall.min && downfall <= config.filter.downfall.max) { + if (!config.toggle.whitelist && !config.toggle.blacklist) { + return true; + } + if (config.toggle.whitelist && config.toggle.blacklist) { + return whitelist.get() && blacklist.get(); + } else if (config.toggle.whitelist) { + return whitelist.get(); + } else if (config.toggle.blacklist) { + return blacklist.get(); + } + } + } + return false; + } + + public boolean canBeeStart() { + if (((BeeEntityInvoker)entity).invokeGetCropsGrownSincePollination() >= 10) { + return false; + } + if (((EntityAccessor)entity).getRandom().nextFloat() > config.value.blossoming.chance) { + return false; + } + if (entity.getWorld().isRaining()) { + return false; + } + Optional optional = findTarget(); + if (optional.isPresent()) { + if (entity.hasNectar()) { + if (((BeeEntityInvoker)entity).invokeIsHiveValid()) { + ((BeeEntityAccessor)entity).setFlowerPos(optional.get()); + ((MobEntityAccessor)entity).getNavigation().startMovingTo((double)entity.getFlowerPos().getX() + 0.5, (double)entity.getFlowerPos().getY() + 0.5, (double)entity.getFlowerPos().getZ() + 0.5, 1.2000000476837158); + return true; + } else { + return false; + } + } else { + return false; + } + } + return false; + } + + public boolean canBeeContinue() { + if (!running) { + return false; + } + if (!entity.hasFlower()) { + return false; + } + if (entity.getFlowerPos() == null) { + return false; + } + if (((BeeEntityInvoker)entity).invokeGetCropsGrownSincePollination() >= 10) { + return false; + } + if (entity.getWorld().isRaining()) { + return false; + } + if (completed()) { + return ((EntityAccessor) entity).getRandom().nextFloat() < 0.2F; + } + if (entity.age % 20 == 0 && !isTarget(entity.getFlowerPos())) { + ((BeeEntityAccessor)entity).setFlowerPos(null); + return false; + } + return true; + } + + public boolean completed() { + return blossomingTicks > 400; + } + + public boolean isRunning() { + return running; + } + + public void cancel() { + running = false; + } + + public void start() { + blossomingTicks = 0; + ticks = 0; + lastBlossomingTick = 0; + running = true; + } + + public void stop() { + if (completed()) { + BlockPos blockPos = entity.getFlowerPos(); + if (blockPos != null) { + BlockState blockState = entity.getWorld().getBlockState(blockPos); + if (blockState.getBlock() == Blocks.OAK_LEAVES) { + entity.getWorld().syncWorldEvent(2005, blockPos, 0); + entity.getWorld().setBlockState(blockPos, FLOWERING_OAK_LEAVES.get().getDefaultState() + .with(DISTANCE, blockState.get(DISTANCE)) + .with(PERSISTENT, blockState.get(PERSISTENT)) + .with(WATERLOGGED, blockState.get(WATERLOGGED)) + ); + ((BeeEntityInvoker)entity).invokeAddCropCounter(); + } + } + } + running = false; + ((MobEntityAccessor)entity).getNavigation().stop(); + } + + public boolean shouldRunEveryTick() { + return true; + } + + public boolean canStart() { + return canBeeStart() && !entity.hasAngerTime() && checkFilters(); + } + + public boolean shouldContinue() { + return canBeeContinue() && !entity.hasAngerTime() && checkFilters(); + } + + public void tick() { + ++ticks; + if (ticks > 600) { + ((BeeEntityAccessor)entity).setFlowerPos(null); + } else { + if (entity.getFlowerPos() != null) { + Vec3d vec3d = Vec3d.ofBottomCenter(entity.getFlowerPos()).add(0.0, 0.6000000238418579, 0.0); + if (vec3d.distanceTo(entity.getPos()) > 1.0) { + nextTarget = vec3d; + moveToNextTarget(); + } else { + if (nextTarget == null) { + nextTarget = vec3d; + } + boolean close = entity.getPos().distanceTo(nextTarget) <= 0.1; + boolean chance = true; + if (!close && ticks > 600) { + ((BeeEntityAccessor)entity).setFlowerPos(null); + } else { + if (close) { + if (((EntityAccessor)entity).getRandom().nextInt(25) == 0) { + nextTarget = new Vec3d(vec3d.getX() + (double)getRandomOffset(), vec3d.getY(), vec3d.getZ() + (double)getRandomOffset()); + ((MobEntityAccessor)entity).getNavigation().stop(); + } else { + chance = false; + } + entity.getLookControl().lookAt(vec3d.getX(), vec3d.getY(), vec3d.getZ()); + } + if (chance) { + moveToNextTarget(); + } + ++blossomingTicks; + if (((EntityAccessor)entity).getRandom().nextFloat() < 0.05F && blossomingTicks > lastBlossomingTick + 60) { + lastBlossomingTick = blossomingTicks; + entity.playSound(SoundEvents.ENTITY_BEE_POLLINATE, 1.0F, 1.0F); + } + } + } + } + } + } + + public boolean isTarget(BlockPos pos) { + return entity.getWorld().canSetBlock(pos) && entity.getWorld().getBlockState(pos).isOf(Blocks.OAK_LEAVES); + } + + public void moveToNextTarget() { + entity.getMoveControl().moveTo(nextTarget.getX(), nextTarget.getY(), nextTarget.getZ(), 0.3499999940395355); + } + + public float getRandomOffset() { + return (((EntityAccessor)entity).getRandom().nextFloat() * 2.0F - 1.0F) * 0.33333334F; + } + + public Optional findTarget() { + return findTarget(targetPredicate, config.value.blossoming.distance); + } + + public Optional findTarget(Predicate predicate, double searchDistance) { + BlockPos blockPos = entity.getBlockPos(); + BlockPos.Mutable mutable = new BlockPos.Mutable(); + for(int i = 0; (double)i <= searchDistance; i = i > 0 ? -i : 1 - i) { + for(int j = 0; (double)j < searchDistance; ++j) { + for(int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { + for(int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { + mutable.set(blockPos, k, i - 1, l); + if (blockPos.isWithinDistance(mutable, searchDistance) && predicate.test(entity.getWorld().getBlockState(mutable))) { + return Optional.of(mutable); + } + } + } + } + } + return Optional.empty(); + } + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/entity/ai/goal/FruitGoal.java b/src/main/java/dev/yurisuika/blossom/entity/ai/goal/FruitGoal.java new file mode 100644 index 0000000..a4bb205 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/entity/ai/goal/FruitGoal.java @@ -0,0 +1,94 @@ +package dev.yurisuika.blossom.entity.ai.goal; + +import dev.yurisuika.blossom.block.FloweringLeavesBlock; +import dev.yurisuika.blossom.mixin.entity.EntityAccessor; +import dev.yurisuika.blossom.mixin.entity.MobEntityAccessor; +import dev.yurisuika.blossom.mixin.entity.passive.BeeEntityAccessor; +import dev.yurisuika.blossom.mixin.entity.passive.BeeEntityInvoker; +import net.minecraft.block.BlockState; +import net.minecraft.entity.passive.BeeEntity; +import net.minecraft.state.property.Properties; +import net.minecraft.util.math.BlockPos; + +import java.util.Optional; +import java.util.function.Predicate; + +import static dev.yurisuika.blossom.Blossom.*; +import static net.minecraft.block.LeavesBlock.*; + +public class FruitGoal extends BlossomGoal { + + public final Predicate targetPredicate = (state) -> { + if (state.contains(Properties.WATERLOGGED) && state.get(Properties.WATERLOGGED)) { + return false; + } else { + if (state.isOf(FLOWERING_OAK_LEAVES.get())) { + return state.get(Properties.AGE_3) >= 3; + } else { + return false; + } + } + }; + + public FruitGoal(BeeEntity beeEntity) { + super(beeEntity); + } + + public boolean canBeeStart() { + if (((BeeEntityInvoker)entity).invokeGetCropsGrownSincePollination() >= 10) { + return false; + } + if (((EntityAccessor)entity).getRandom().nextFloat() > config.value.fruiting.chance) { + return false; + } + if (entity.getWorld().isRaining()) { + return false; + } + Optional optional = findTarget(); + if (optional.isPresent()) { + if (entity.hasNectar()) { + if (((BeeEntityInvoker)entity).invokeIsHiveValid()) { + ((BeeEntityAccessor)entity).setFlowerPos(optional.get()); + ((MobEntityAccessor)entity).getNavigation().startMovingTo((double)entity.getFlowerPos().getX() + 0.5, (double)entity.getFlowerPos().getY() + 0.5, (double)entity.getFlowerPos().getZ() + 0.5, 1.2000000476837158); + return true; + } else { + return false; + } + } else { + return false; + } + } + return false; + } + + public void stop() { + if (completed()) { + BlockPos blockPos = entity.getFlowerPos(); + if (blockPos != null) { + BlockState blockState = entity.getWorld().getBlockState(blockPos); + if (blockState.getBlock() == FLOWERING_OAK_LEAVES.get()) { + if (blockState.get(Properties.AGE_3) >= 3) { + entity.getWorld().syncWorldEvent(2005, blockPos, 0); + entity.getWorld().setBlockState(blockPos, FRUITING_OAK_LEAVES.get().getDefaultState() + .with(DISTANCE, blockState.get(DISTANCE)) + .with(PERSISTENT, blockState.get(PERSISTENT)) + .with(WATERLOGGED, blockState.get(WATERLOGGED)) + ); + ((BeeEntityInvoker)entity).invokeAddCropCounter(); + } + } + } + } + running = false; + ((MobEntityAccessor)entity).getNavigation().stop(); + } + + public boolean isTarget(BlockPos pos) { + return entity.getWorld().canSetBlock(pos) && entity.getWorld().getBlockState(pos).getBlock() instanceof FloweringLeavesBlock; + } + + public Optional findTarget() { + return findTarget(targetPredicate, config.value.fruiting.distance); + } + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/block/AbstractBlockMixin.java b/src/main/java/dev/yurisuika/blossom/mixin/block/AbstractBlockMixin.java new file mode 100644 index 0000000..186cd49 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/mixin/block/AbstractBlockMixin.java @@ -0,0 +1,31 @@ +package dev.yurisuika.blossom.mixin.block; + +import net.minecraft.block.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.BeeEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(AbstractBlock.class) +public abstract class AbstractBlockMixin { + + @Inject(method = "getCollisionShape", at = @At("HEAD"), cancellable = true) + private void injectGetCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, CallbackInfoReturnable cir) { + Entity entity = null; + if (context instanceof EntityShapeContext) { + entity = ((EntityShapeContext)context).getEntity(); + if (entity instanceof BeeEntity) { + if (state.getBlock() instanceof LeavesBlock) { + cir.setReturnValue(VoxelShapes.empty()); + } + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/block/BlocksInvoker.java b/src/main/java/dev/yurisuika/blossom/mixin/block/BlocksInvoker.java new file mode 100644 index 0000000..53a9b30 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/mixin/block/BlocksInvoker.java @@ -0,0 +1,24 @@ +package dev.yurisuika.blossom.mixin.block; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockView; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Blocks.class) +public interface BlocksInvoker { + + @Invoker("never") + static boolean invokeNever(BlockState state, BlockView world, BlockPos pos) { + throw new AssertionError(); + } + + @Invoker("canSpawnOnLeaves") + static Boolean invokeCanSpawnOnLeaves(BlockState state, BlockView world, BlockPos pos, EntityType type) { + throw new AssertionError(); + } + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/block/LeavesBlockMixin.java b/src/main/java/dev/yurisuika/blossom/mixin/block/LeavesBlockMixin.java index 4e66a44..7426512 100644 --- a/src/main/java/dev/yurisuika/blossom/mixin/block/LeavesBlockMixin.java +++ b/src/main/java/dev/yurisuika/blossom/mixin/block/LeavesBlockMixin.java @@ -10,7 +10,7 @@ import static net.minecraft.block.LeavesBlock.DISTANCE; @Mixin(LeavesBlock.class) -public class LeavesBlockMixin { +public abstract class LeavesBlockMixin { @Inject(method = "getDistanceFromLog(Lnet/minecraft/block/BlockState;)I", at = @At("RETURN"), cancellable = true) private static void injectDistance(BlockState state, CallbackInfoReturnable info) { diff --git a/src/main/java/dev/yurisuika/blossom/mixin/entity/EntityAccessor.java b/src/main/java/dev/yurisuika/blossom/mixin/entity/EntityAccessor.java new file mode 100644 index 0000000..a1cadae --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/mixin/entity/EntityAccessor.java @@ -0,0 +1,14 @@ +package dev.yurisuika.blossom.mixin.entity; + +import net.minecraft.entity.Entity; +import net.minecraft.util.math.random.Random; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Entity.class) +public interface EntityAccessor { + + @Accessor + Random getRandom(); + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/entity/MobEntityAccessor.java b/src/main/java/dev/yurisuika/blossom/mixin/entity/MobEntityAccessor.java new file mode 100644 index 0000000..3d13874 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/mixin/entity/MobEntityAccessor.java @@ -0,0 +1,14 @@ +package dev.yurisuika.blossom.mixin.entity; + +import net.minecraft.entity.ai.pathing.EntityNavigation; +import net.minecraft.entity.mob.MobEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(MobEntity.class) +public interface MobEntityAccessor { + + @Accessor + EntityNavigation getNavigation(); + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/entity/ai/goal/GoalInvoker.java b/src/main/java/dev/yurisuika/blossom/mixin/entity/ai/goal/GoalInvoker.java new file mode 100644 index 0000000..5484755 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/mixin/entity/ai/goal/GoalInvoker.java @@ -0,0 +1,13 @@ +package dev.yurisuika.blossom.mixin.entity.ai.goal; + +import net.minecraft.entity.ai.goal.Goal; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Goal.class) +public interface GoalInvoker { + + @Invoker("getTickCount") + int invokeGetTickCount(int ticks); + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityAccessor.java b/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityAccessor.java new file mode 100644 index 0000000..c5b38a0 --- /dev/null +++ b/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityAccessor.java @@ -0,0 +1,14 @@ +package dev.yurisuika.blossom.mixin.entity.passive; + +import net.minecraft.entity.passive.BeeEntity; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(BeeEntity.class) +public interface BeeEntityAccessor { + + @Accessor("flowerPos") + void setFlowerPos(BlockPos flowerPos); + +} \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityInvoker.java b/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityInvoker.java index 5a489f9..3f15a89 100644 --- a/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityInvoker.java +++ b/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityInvoker.java @@ -1,13 +1,21 @@ package dev.yurisuika.blossom.mixin.entity.passive; import net.minecraft.entity.passive.BeeEntity; +import org.spongepowered.asm.mixin.Intrinsic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(BeeEntity.class) public interface BeeEntityInvoker { + @Intrinsic @Invoker("addCropCounter") void invokeAddCropCounter(); + @Invoker("isHiveValid") + boolean invokeIsHiveValid(); + + @Invoker("getCropsGrownSincePollination") + int invokeGetCropsGrownSincePollination(); + } \ No newline at end of file diff --git a/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityMixin.java b/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityMixin.java index b71c210..93d7617 100644 --- a/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityMixin.java +++ b/src/main/java/dev/yurisuika/blossom/mixin/entity/passive/BeeEntityMixin.java @@ -1,55 +1,51 @@ package dev.yurisuika.blossom.mixin.entity.passive; -import dev.yurisuika.blossom.block.FloweringLeavesBlock; -import dev.yurisuika.blossom.mixin.world.biome.BiomeAccessor; +import dev.yurisuika.blossom.block.FruitingLeavesBlock; +import dev.yurisuika.blossom.mixin.entity.ai.goal.GoalInvoker; import net.minecraft.block.*; import net.minecraft.entity.passive.BeeEntity; import net.minecraft.state.property.IntProperty; -import net.minecraft.state.property.Properties; import net.minecraft.tag.BlockTags; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.registry.RegistryEntry; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.WorldView; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Arrays; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Predicate; - -import static dev.yurisuika.blossom.Blossom.*; -import static net.minecraft.block.LeavesBlock.*; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(BeeEntity.class) -public class BeeEntityMixin { +public abstract class BeeEntityMixin { + + @Inject(method = "getPathfindingFavor", at = @At("HEAD"), cancellable = true) + private void injectGetPathfindingFavor(BlockPos pos, WorldView world, CallbackInfoReturnable cir) { + if (world.getBlockState(pos).getBlock() instanceof LeavesBlock) { + cir.setReturnValue(0.0F); + } + } @Mixin(targets = "net.minecraft.entity.passive.BeeEntity$GrowCropsGoal") - public static class GrowCropsGoalMixin { + public abstract static class GrowCropsGoalMixin { @Unique - private BeeEntity entity; + public BeeEntity entity; @Inject(method = "", at = @At(value = "TAIL")) - private void injectInit(BeeEntity entityType, CallbackInfo ci) { - entity = entityType; + private void injectInit(BeeEntity beeEntity, CallbackInfo ci) { + entity = beeEntity; } @Inject(method = "tick", at = @At(value = "HEAD")) private void injectTick(CallbackInfo ci) { - if (ThreadLocalRandom.current().nextDouble() <= config.value.fertilization.chance) { + if (entity.getRandom().nextInt(((GoalInvoker)this).invokeGetTickCount(30)) != 0) { for (int i = 1; i <= 2; ++i) { BlockPos blockPos = entity.getBlockPos().down(i); BlockState blockState = entity.getWorld().getBlockState(blockPos); if (blockState.isIn(BlockTags.BEE_GROWABLES)) { - if (blockState.getBlock() instanceof FloweringLeavesBlock floweringLeavesBlock) { - if (!floweringLeavesBlock.isMature(blockState)) { - IntProperty age = floweringLeavesBlock.getAgeProperty(); + if (blockState.getBlock() instanceof FruitingLeavesBlock fruitingLeavesBlock) { + if (!fruitingLeavesBlock.isMature(blockState)) { + IntProperty age = fruitingLeavesBlock.getAgeProperty(); entity.getWorld().syncWorldEvent(2005, blockPos, 0); entity.getWorld().setBlockState(blockPos, blockState.with(age, blockState.get(age) + 1)); ((BeeEntityInvoker)entity).invokeAddCropCounter(); @@ -58,76 +54,24 @@ private void injectTick(CallbackInfo ci) { } } } + } - RegistryEntry dimension = entity.getWorld().getDimensionEntry(); - RegistryEntry biome = entity.getWorld().getBiome(entity.getBlockPos()); - float temperature = biome.value().getTemperature(); - float downfall = ((BiomeAccessor)(Object)biome.value()).getWeather().downfall(); - - boolean whitelist = false; - if (Arrays.asList(config.filter.dimension.whitelist).contains(dimension.getKey().get().getValue().toString()) && dimension.getKey().isPresent()) { - if (Arrays.asList(config.filter.biome.whitelist).contains(biome.getKey().get().getValue().toString()) && biome.getKey().isPresent()) { - whitelist = true; - } - } + } - boolean blacklist = false; - if (!Arrays.asList(config.filter.dimension.blacklist).contains(dimension.getKey().get().getValue().toString()) && dimension.getKey().isPresent()) { - if (!Arrays.asList(config.filter.biome.blacklist).contains(biome.getKey().get().getValue().toString()) && biome.getKey().isPresent()) { - blacklist = true; - } - } + @Mixin(targets = "net.minecraft.entity.passive.BeeEntity$MoveToFlowerGoal") + public abstract static class MoveToFlowerGoalMixin { - boolean enabled = false; - if (temperature >= config.filter.temperature.min && temperature <= config.filter.temperature.max) { - if (downfall >= config.filter.downfall.min && downfall <= config.filter.downfall.max) { - if (config.toggle.whitelist && config.toggle.blacklist) { - if (whitelist && blacklist) { - enabled = true; - } - } else if (config.toggle.whitelist) { - if (whitelist) { - enabled = true; - } - } else if (config.toggle.blacklist) { - if (blacklist) { - enabled = true; - } - } else { - enabled = true; - } - } - } + @Unique + public BeeEntity entity; - if (enabled) { - if (ThreadLocalRandom.current().nextDouble() <= config.value.propagation.chance) { - for (int i = 1; i <= 2; ++i) { - BlockPos blockPos = entity.getBlockPos().down(i); - BlockState blockState = entity.getWorld().getBlockState(blockPos); - if (Arrays.stream(Direction.values()).anyMatch(direction -> !entity.getWorld().getBlockState(blockPos.offset(direction)).getMaterial().isSolid())) { - if (blockState.getBlock() == Blocks.OAK_LEAVES) { - entity.getWorld().syncWorldEvent(2005, blockPos, 0); - entity.getWorld().setBlockState(blockPos, FLOWERING_OAK_LEAVES.get().getDefaultState() - .with(DISTANCE, blockState.get(DISTANCE)) - .with(PERSISTENT, blockState.get(PERSISTENT)) - .with(WATERLOGGED, blockState.get(WATERLOGGED)) - ); - ((BeeEntityInvoker)entity).invokeAddCropCounter(); - } - } - } - } - } + @Inject(method = "", at = @At(value = "TAIL")) + private void injectInit(BeeEntity beeEntity, CallbackInfo ci) { + entity = beeEntity; } - } - - @Mixin(targets = "net.minecraft.entity.passive.BeeEntity$PollinateGoal") - public abstract static class PollinateGoalMixin { - - @ModifyArg(method = "getFlower", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/BeeEntity$PollinateGoal;findFlower(Ljava/util/function/Predicate;D)Ljava/util/Optional;"), index = 0) - private Predicate modifyGetFlower(Predicate predicate) { - return predicate.and((state) -> state.getBlock() instanceof FloweringLeavesBlock ? state.get(Properties.AGE_7) <= config.value.pollination.age : true); + @Inject(method = "shouldMoveToFlower", at = @At("RETURN"), cancellable = true) + private void injectTick(CallbackInfoReturnable cir) { + cir.setReturnValue(cir.getReturnValue() || (entity.getWorld().getBlockState(entity.getFlowerPos()).isOf(Blocks.OAK_LEAVES) && entity.hasNectar())); } } diff --git a/src/main/java/dev/yurisuika/blossom/server/command/BlossomCommand.java b/src/main/java/dev/yurisuika/blossom/server/command/BlossomCommand.java index 448a0fa..819174c 100644 --- a/src/main/java/dev/yurisuika/blossom/server/command/BlossomCommand.java +++ b/src/main/java/dev/yurisuika/blossom/server/command/BlossomCommand.java @@ -8,7 +8,11 @@ import net.minecraft.command.argument.RegistryPredicateArgumentType; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.HoverEvent; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import net.minecraft.text.Texts; +import net.minecraft.util.Formatting; import net.minecraft.util.registry.Registry; import org.apache.commons.lang3.ArrayUtils; @@ -26,6 +30,7 @@ public static void register(CommandDispatcher dispatcher, C .then(literal("reload") .executes(context -> { loadConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.config.reload"), true); return 1; }) @@ -33,10 +38,9 @@ public static void register(CommandDispatcher dispatcher, C .then(literal("reset") .executes(context -> { config.value = new Value( - new Value.Propagation(0.2F), - new Value.Fertilization(0.06666667F), - new Value.Pollination(1), - new Value.Fruit(3, 0.5714286F) + new Value.Blossoming(0.2F, 10.0D), + new Value.Fruiting(0.2F, 10.0D), + new Value.Harvesting(3, 0.5714286F) ); config.filter = new Filter( new Filter.Temperature(-2.0F, 2.0F), @@ -49,6 +53,7 @@ public static void register(CommandDispatcher dispatcher, C false ); saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.config.reset"), true); return 1; }) @@ -56,62 +61,74 @@ public static void register(CommandDispatcher dispatcher, C ) .then(literal("value") .requires(source -> source.hasPermissionLevel(4)) - .then(literal("propagation") + .then(literal("blossoming") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.propagation.query", config.value.propagation.chance), false); + MutableText chance = Texts.bracketed(Text.translatable("commands.blossom.value.blossoming.chance", config.value.blossoming.chance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.blossoming.chance.tooltip")))); + MutableText distance = Texts.bracketed(Text.translatable("commands.blossom.value.blossoming.distance", config.value.blossoming.distance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.blossoming.distance.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.value.blossoming.query", chance, distance), true); return 1; }) .then(CommandManager.argument("chance", FloatArgumentType.floatArg(0.0F, 1.0F)) - .executes(context -> { - config.value.propagation.chance = FloatArgumentType.getFloat(context, "chance"); - saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.propagation.set", config.value.propagation.chance), true); - return 1; - }) + .then(CommandManager.argument("distance", DoubleArgumentType.doubleArg(0.0D)) + .executes(context -> { + config.value.blossoming.chance = FloatArgumentType.getFloat(context, "chance"); + config.value.blossoming.distance = DoubleArgumentType.getDouble(context, "distance"); + saveConfig(); + + MutableText chance = Texts.bracketed(Text.translatable("commands.blossom.value.blossoming.chance", config.value.blossoming.chance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.blossoming.chance.tooltip")))); + MutableText distance = Texts.bracketed(Text.translatable("commands.blossom.value.blossoming.distance", config.value.blossoming.distance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.blossoming.distance.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.value.blossoming.set", chance, distance), true); + return 1; + }) + ) ) ) - .then(literal("fertilization") + .then(literal("fruiting") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.fertilization.query", config.value.fertilization.chance), false); + MutableText chance = Texts.bracketed(Text.translatable("commands.blossom.value.fruiting.chance", config.value.fruiting.chance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.fruiting.chance.tooltip")))); + MutableText distance = Texts.bracketed(Text.translatable("commands.blossom.value.fruiting.distance", config.value.fruiting.distance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.blossoming.fruiting.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.value.fruiting.query", chance, distance), false); return 1; }) .then(CommandManager.argument("chance", FloatArgumentType.floatArg(0.0F, 1.0F)) - .executes(context -> { - config.value.fertilization.chance = FloatArgumentType.getFloat(context, "chance"); - saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.fertilization.set", config.value.fertilization.chance), true); - return 1; - }) - ) - ) - .then(literal("pollination") - .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.pollination.query", config.value.pollination.age), false); - return 1; - }) - .then(CommandManager.argument("age", IntegerArgumentType.integer(0, 7)) - .executes(context -> { - config.value.pollination.age = IntegerArgumentType.getInteger(context, "age"); - saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.pollination.set", config.value.pollination.age), true); - return 1; - }) + .then(CommandManager.argument("distance", DoubleArgumentType.doubleArg(0.0D)) + .executes(context -> { + config.value.fruiting.chance = FloatArgumentType.getFloat(context, "chance"); + config.value.fruiting.distance = DoubleArgumentType.getDouble(context, "distance"); + saveConfig(); + + MutableText chance = Texts.bracketed(Text.translatable("commands.blossom.value.fruiting.chance", config.value.fruiting.chance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.fruiting.chance.tooltip")))); + MutableText distance = Texts.bracketed(Text.translatable("commands.blossom.value.fruiting.distance", config.value.fruiting.distance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.blossoming.fruiting.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.value.fruiting.set", chance, distance), false); + return 1; + }) + ) ) ) - .then(literal("fruit") + .then(literal("harvesting") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.fruit.query", config.value.fruit.bonus, config.value.fruit.chance), false); + MutableText bonus = Texts.bracketed(Text.translatable("commands.blossom.value.harvesting.bonus", config.value.harvesting.bonus)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.harvesting.bonus.tooltip")))); + + MutableText chance = Texts.bracketed(Text.translatable("commands.blossom.value.harvesting.chance", config.value.harvesting.chance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.harvesting.chance.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.value.harvesting.query", bonus, chance), true); return 1; }) .then(CommandManager.argument("bonus", IntegerArgumentType.integer(0)) .then(CommandManager.argument("chance", FloatArgumentType.floatArg(0.0F, 1.0F)) .executes(context -> { - int bonus = IntegerArgumentType.getInteger(context, "bonus"); - float chance = FloatArgumentType.getFloat(context, "chance"); - config.value.fruit.bonus = bonus; - config.value.fruit.chance = chance; + config.value.harvesting.bonus = IntegerArgumentType.getInteger(context, "bonus"); + config.value.harvesting.chance = FloatArgumentType.getFloat(context, "chance"); saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.value.fruit.set", bonus, chance), true); + + MutableText bonus = Texts.bracketed(Text.translatable("commands.blossom.value.harvesting.bonus", config.value.harvesting.bonus)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.harvesting.bonus.tooltip")))); + MutableText chance = Texts.bracketed(Text.translatable("commands.blossom.value.harvesting.chance", config.value.harvesting.chance)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.value.harvesting.chance.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.value.harvesting.set", bonus, chance), true); return 1; }) ) @@ -122,17 +139,22 @@ public static void register(CommandDispatcher dispatcher, C .requires(source -> source.hasPermissionLevel(4)) .then(literal("temperature") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.temperature.query", config.filter.temperature.min, config.filter.temperature.max), false); + MutableText min = Texts.bracketed(Text.translatable("commands.blossom.filter.temperature.min", config.filter.temperature.min)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.temperature.min.tooltip")))); + MutableText max = Texts.bracketed(Text.translatable("commands.blossom.filter.temperature.max", config.filter.temperature.max)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.temperature.max.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.temperature.query", min, max), false); return 1; }) .then(argument("min", FloatArgumentType.floatArg(-2.0F, 2.0F)) .then(argument("max", FloatArgumentType.floatArg(-2.0F, 2.0F)) .executes(context -> { - float min = Math.min(FloatArgumentType.getFloat(context, "min"), FloatArgumentType.getFloat(context, "max")); - float max = Math.max(FloatArgumentType.getFloat(context, "max"), FloatArgumentType.getFloat(context, "min")); - config.filter.temperature.min = min; - config.filter.temperature.max = max; + config.filter.temperature.min = Math.min(FloatArgumentType.getFloat(context, "min"), FloatArgumentType.getFloat(context, "max")); + config.filter.temperature.max = Math.max(FloatArgumentType.getFloat(context, "max"), FloatArgumentType.getFloat(context, "min")); saveConfig(); + + MutableText min = Texts.bracketed(Text.translatable("commands.blossom.filter.temperature.min", config.filter.temperature.min)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.temperature.min.tooltip")))); + MutableText max = Texts.bracketed(Text.translatable("commands.blossom.filter.temperature.max", config.filter.temperature.max)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.temperature.max.tooltip")))); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.temperature.set", min, max), false); return 1; }) @@ -141,18 +163,23 @@ public static void register(CommandDispatcher dispatcher, C ) .then(literal("downfall") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.downfall.query", config.filter.downfall.min, config.filter.downfall.max), false); + MutableText min = Texts.bracketed(Text.translatable("commands.blossom.filter.downfall.min", config.filter.downfall.min)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.downfall.min.tooltip")))); + MutableText max = Texts.bracketed(Text.translatable("commands.blossom.filter.downfall.max", config.filter.downfall.max)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.downfall.max.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.temperature.query", min, max), false); return 1; }) .then(argument("min", FloatArgumentType.floatArg(0.0F, 1.0F)) .then(argument("max", FloatArgumentType.floatArg(0.0F, 1.0F)) .executes(context -> { - float min = Math.min(FloatArgumentType.getFloat(context, "min"), FloatArgumentType.getFloat(context, "max")); - float max = Math.max(FloatArgumentType.getFloat(context, "max"), FloatArgumentType.getFloat(context, "min")); - config.filter.downfall.min = min; - config.filter.downfall.max = max; + config.filter.downfall.min = Math.min(FloatArgumentType.getFloat(context, "min"), FloatArgumentType.getFloat(context, "max")); + config.filter.downfall.max = Math.max(FloatArgumentType.getFloat(context, "max"), FloatArgumentType.getFloat(context, "min")); saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.downfall.set", min, max), false); + + MutableText min = Texts.bracketed(Text.translatable("commands.blossom.filter.downfall.min", config.filter.downfall.min)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.downfall.min.tooltip")))); + MutableText max = Texts.bracketed(Text.translatable("commands.blossom.filter.downfall.max", config.filter.downfall.max)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.downfall.max.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.temperature.set", min, max), false); return 1; }) ) @@ -161,7 +188,9 @@ public static void register(CommandDispatcher dispatcher, C .then(literal("dimension") .then(literal("whitelist") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.whitelist.query", String.join(", ", config.filter.dimension.whitelist)), false); + MutableText list = Text.translatable("commands.blossom.filter.dimension.whitelist.list", Arrays.toString(config.filter.dimension.whitelist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.dimension.whitelist.list.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.whitelist.query", list), false); return 1; }) .then(literal("add") @@ -175,6 +204,7 @@ public static void register(CommandDispatcher dispatcher, C config.filter.dimension.whitelist = ArrayUtils.add(config.filter.dimension.whitelist, dimension); Arrays.sort(config.filter.dimension.whitelist); saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.whitelist.add", dimension), false); return 1; } @@ -196,6 +226,7 @@ public static void register(CommandDispatcher dispatcher, C } } saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.whitelist.remove", dimension), false); return 1; } @@ -205,7 +236,9 @@ public static void register(CommandDispatcher dispatcher, C ) .then(literal("blacklist") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.blacklist.query", String.join(", ", config.filter.dimension.blacklist)), false); + MutableText list = Text.translatable("commands.blossom.filter.dimension.blacklist.list", Arrays.toString(config.filter.dimension.blacklist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.dimension.blacklist.list.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.blacklist.query", list), false); return 1; }) .then(literal("add") @@ -219,6 +252,7 @@ public static void register(CommandDispatcher dispatcher, C config.filter.dimension.blacklist = ArrayUtils.add(config.filter.dimension.blacklist, dimension); Arrays.sort(config.filter.dimension.blacklist); saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.blacklist.add", dimension), false); return 1; } @@ -240,6 +274,7 @@ public static void register(CommandDispatcher dispatcher, C } } saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.dimension.blacklist.remove", dimension), false); return 1; } @@ -251,7 +286,9 @@ public static void register(CommandDispatcher dispatcher, C .then(literal("biome") .then(literal("whitelist") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.whitelist.query", String.join(", ", config.filter.biome.whitelist)), false); + MutableText list = Text.translatable("commands.blossom.filter.biome.whitelist.list", Arrays.toString(config.filter.biome.whitelist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.biome.whitelist.list.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.whitelist.query", list), false); return 1; }) .then(literal("add") @@ -265,6 +302,7 @@ public static void register(CommandDispatcher dispatcher, C config.filter.biome.whitelist = ArrayUtils.add(config.filter.biome.whitelist, biome); Arrays.sort(config.filter.biome.whitelist); saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.whitelist.add", biome), false); return 1; } @@ -286,6 +324,7 @@ public static void register(CommandDispatcher dispatcher, C } } saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.whitelist.remove", biome), false); return 1; } @@ -295,7 +334,9 @@ public static void register(CommandDispatcher dispatcher, C ) .then(literal("blacklist") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.blacklist.query", String.join(", ", config.filter.biome.blacklist)), false); + MutableText list = Text.translatable("commands.blossom.filter.biome.blacklist.list", Arrays.toString(config.filter.biome.blacklist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.filter.biome.blacklist.list.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.blacklist.query", list), false); return 1; }) .then(literal("add") @@ -309,6 +350,7 @@ public static void register(CommandDispatcher dispatcher, C config.filter.biome.blacklist = ArrayUtils.add(config.filter.biome.blacklist, biome); Arrays.sort(config.filter.biome.blacklist); saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.blacklist.add", biome), false); return 1; } @@ -330,6 +372,7 @@ public static void register(CommandDispatcher dispatcher, C } } saveConfig(); + context.getSource().sendFeedback(Text.translatable("commands.blossom.filter.biome.blacklist.remove", biome), false); return 1; } @@ -343,28 +386,38 @@ public static void register(CommandDispatcher dispatcher, C .requires(source -> source.hasPermissionLevel(4)) .then(literal("whitelist") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.whitelist.query", config.toggle.whitelist), false); + MutableText toggle = Texts.bracketed(Text.translatable("commands.blossom.toggle.whitelist.toggle", config.toggle.whitelist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.toggle.whitelist.toggle.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.whitelist.query", toggle), false); return 1; }) .then(argument("value", BoolArgumentType.bool()) .executes(context -> { config.toggle.whitelist = BoolArgumentType.getBool(context, "value"); saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.whitelist.set", config.toggle.whitelist), false); + + MutableText toggle = Texts.bracketed(Text.translatable("commands.blossom.toggle.whitelist.toggle", config.toggle.whitelist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.toggle.whitelist.toggle.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.whitelist.set", toggle), false); return 1; }) ) ) .then(literal("blacklist") .executes(context -> { - context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.blacklist.query", config.toggle.blacklist), false); + MutableText toggle = Texts.bracketed(Text.translatable("commands.blossom.toggle.blacklist.toggle", config.toggle.blacklist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.toggle.blacklist.toggle.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.blacklist.query", toggle), false); return 1; }) .then(argument("value", BoolArgumentType.bool()) .executes(context -> { config.toggle.blacklist = BoolArgumentType.getBool(context, "value"); saveConfig(); - context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.blacklist.set", config.toggle.blacklist), false); + + MutableText toggle = Texts.bracketed(Text.translatable("commands.blossom.toggle.blacklist.toggle", config.toggle.blacklist)).styled(style -> style.withColor(Formatting.GREEN).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("commands.blossom.toggle.blacklist.toggle.tooltip")))); + + context.getSource().sendFeedback(Text.translatable("commands.blossom.toggle.blacklist.set", toggle), false); return 1; }) ) diff --git a/src/main/resources/assets/blossom/blockstates/flowering_oak_leaves.json b/src/main/resources/assets/blossom/blockstates/flowering_oak_leaves.json index 8fd8f02..171224f 100644 --- a/src/main/resources/assets/blossom/blockstates/flowering_oak_leaves.json +++ b/src/main/resources/assets/blossom/blockstates/flowering_oak_leaves.json @@ -1,28 +1,45 @@ { - "multipart": [ - { "when": { "age": "0" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage0" } - }, - { "when": { "age": "1" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage1" } - }, - { "when": { "age": "2" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage2" } - }, - { "when": { "age": "3" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage3" } - }, - { "when": { "age": "4" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage4" } - }, - { "when": { "age": "5" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage5" } - }, - { "when": { "age": "6" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage6" } - }, - { "when": { "age": "7" }, - "apply": { "model": "blossom:block/flowering_oak_leaves_stage7" } - } + "variants": { + "age=0": [ + { + "model": "blossom:block/flowering_oak_leaves_stage0" + } + ], + "age=1": [ + { + "model": "blossom:block/flowering_oak_leaves_stage1a" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage1b" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage1c" + } + ], + "age=2": [ + { + "model": "blossom:block/flowering_oak_leaves_stage2a" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage2b" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage2c" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage2c" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage2a" + }, + { + "model": "blossom:block/flowering_oak_leaves_stage2b" + } + ], + "age=3": [ + { + "model": "blossom:block/flowering_oak_leaves_stage3" + } ] + } } \ No newline at end of file diff --git a/src/main/resources/assets/blossom/blockstates/fruiting_oak_leaves.json b/src/main/resources/assets/blossom/blockstates/fruiting_oak_leaves.json new file mode 100644 index 0000000..9d32031 --- /dev/null +++ b/src/main/resources/assets/blossom/blockstates/fruiting_oak_leaves.json @@ -0,0 +1,44 @@ +{ + "variants": { + "age=0": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage0" + } + ], + "age=1": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage1" + } + ], + "age=2": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage2" + } + ], + "age=3": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage3" + } + ], + "age=4": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage4" + } + ], + "age=5": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage5" + } + ], + "age=6": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage6" + } + ], + "age=7": [ + { + "model": "blossom:block/fruiting_oak_leaves_stage7" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/icon.png b/src/main/resources/assets/blossom/icon.png new file mode 100644 index 0000000..1a2b58e Binary files /dev/null and b/src/main/resources/assets/blossom/icon.png differ diff --git a/src/main/resources/assets/blossom/lang/en_us.json b/src/main/resources/assets/blossom/lang/en_us.json index d1f8290..8f9223c 100644 --- a/src/main/resources/assets/blossom/lang/en_us.json +++ b/src/main/resources/assets/blossom/lang/en_us.json @@ -1,54 +1,84 @@ { "block.blossom.flowering_oak_leaves": "Flowering Oak Leaves", + "block.blossom.fruiting_oak_leaves": "Fruiting Oak Leaves", "commands.blossom.config.reload": "Blossom config reloaded", "commands.blossom.config.reset": "Blossom config reset to defaults", - "commands.blossom.value.propagation.query": "Propagation is currently set to: (chance: %s)", - "commands.blossom.value.propagation.set": "Propagation is now set to: (chance: %s)", + "commands.blossom.value.blossoming.query": "Blossoming is currently set to: %s %s", + "commands.blossom.value.blossoming.set": "Blossoming is now set to: %s %s", + "commands.blossom.value.blossoming.chance": "Chance: %s", + "commands.blossom.value.blossoming.chance.tooltip": "Chance for bees to start blossoming flowering leaves\n&7(min: 0.0, max: 1.0)", + "commands.blossom.value.blossoming.distance": "Distance: %s", + "commands.blossom.value.blossoming.distance.tooltip": "Distance bees will search for leaves to blossom\n&7(min: 0.0)", - "commands.blossom.value.fertilization.query": "Fertilization is currently set to: (chance: %s)", - "commands.blossom.value.fertilization.set": "Fertilization is now set to: (chance: %s)", + "commands.blossom.value.fruiting.query": "Fruiting is currently set to: %s %s", + "commands.blossom.value.fruiting.set": "Fruiting is now set to: %s %s", + "commands.blossom.value.fruiting.chance": "Chance: %s", + "commands.blossom.value.fruiting.chance.tooltip": "Chance for bees to fertilize fruiting leaves\n&7(min: 0.0, max: 1.0)", + "commands.blossom.value.fruiting..distance": "Distance: %s", + "commands.blossom.value.fruiting..distance.tooltip": "Distance bees will search for leaves to fruit\n&7(min: 0.0)", - "commands.blossom.value.pollination.query": "Pollination is currently set to: (age: %s)", - "commands.blossom.value.pollination.set": "Pollination is now set to: (age: %s)", + "commands.blossom.value.harvesting.query": "Harvesting is currently set to: %s %s", + "commands.blossom.value.harvesting.set": "Harvesting is now set to: %s %s", + "commands.blossom.value.harvesting.bonus": "Bonus: %s", + "commands.blossom.value.harvesting.bonus.tooltip": "Amount of bonus fruits to harvest\n&7(min: 0)", + "commands.blossom.value.harvesting.chance": "Chance: %s", + "commands.blossom.value.harvesting.chance.tooltip": "Chance to harvest each bonus fruit\n&7(min: 0.0, max: 1.0)", - "commands.blossom.value.fruit.query": "Fruit is currently set to: (bonus: %s, chance: %s)", - "commands.blossom.value.fruit.set": "Fruit is now set to: (bonus: %s, chance: %s)", + "commands.blossom.filter.temperature.query": "Temperature is currently set to: %s %s", + "commands.blossom.filter.temperature.set": "Temperature is now set to: %s %s", + "commands.blossom.filter.temperature.min": "Min: %s", + "commands.blossom.filter.temperature.min.tooltip": "Minimum temperature to allow blossoming\n&7(min: -2.0, max: 2.0)", + "commands.blossom.filter.temperature.max": "Max: %s", + "commands.blossom.filter.temperature.max.tooltip": "Maximum temperature to allow blossoming\n&7(min: -2.0, max: 2.0)", - "commands.blossom.filter.temperature.query": "Temperature is currently set to: (min: %s, max: %s)", - "commands.blossom.filter.temperature.set": "Temperature is now set to: (min: %s, max: %s)", - - "commands.blossom.filter.downfall.query": "Downfall is currently set to: (min: %s, max: %s)", - "commands.blossom.filter.downfall.set": "Downfall is now set to: (min: %s, max: %s)", + "commands.blossom.filter.downfall.query": "Downfall is currently set to: %s %s", + "commands.blossom.filter.downfall.set": "Downfall is now set to: %s %s", + "commands.blossom.filter.downfall.min": "Min: %s", + "commands.blossom.filter.downfall.min.tooltip": "Minimum downfall to allow blossoming\n&7(min: 0.0, max: 1.0)", + "commands.blossom.filter.downfall.max": "Max: %s", + "commands.blossom.filter.downfall.max.tooltip": "Maximum downfall to allow blossoming\n&7(min: 0.0, max: 1.0)", "commands.blossom.filter.dimension.whitelist.query": "Whitelisted dimensions: %s", - "commands.blossom.filter.dimension.whitelist.add": "Added dimension '%s' to whitelist", - "commands.blossom.filter.dimension.whitelist.add.failed": "Dimension '%s' is already in whitelist", - "commands.blossom.filter.dimension.whitelist.remove": "Removed dimension '%s' from whitelist", - "commands.blossom.filter.dimension.whitelist.remove.failed": "Dimension '%s' is not in whitelist", + "commands.blossom.filter.dimension.whitelist.list": "%s", + "commands.blossom.filter.dimension.whitelist.list.tooltip": "Dimensions that allow blossoming", + "commands.blossom.filter.dimension.whitelist.add": "Added dimension entry '%s' to whitelist", + "commands.blossom.filter.dimension.whitelist.add.failed": "Dimension entry '%s' is already in whitelist", + "commands.blossom.filter.dimension.whitelist.remove": "Removed dimension entry '%s' from whitelist", + "commands.blossom.filter.dimension.whitelist.remove.failed": "Dimension entry '%s' is not in whitelist", "commands.blossom.filter.dimension.blacklist.query": "Blacklisted dimensions: %s", - "commands.blossom.filter.dimension.blacklist.add": "Added dimension '%s' to blacklist", - "commands.blossom.filter.dimension.blacklist.add.failed": "Dimension '%s' is already in blacklist", - "commands.blossom.filter.dimension.blacklist.remove": "Removed dimension '%s' from blacklist", - "commands.blossom.filter.dimension.blacklist.remove.failed": "Dimension '%s' is not in blacklist", + "commands.blossom.filter.dimension.blacklist.list": "%s", + "commands.blossom.filter.dimension.blacklist.list.tooltip": "Dimensions that disallow blossoming", + "commands.blossom.filter.dimension.blacklist.add": "Added dimension entry '%s' to blacklist", + "commands.blossom.filter.dimension.blacklist.add.failed": "Dimension entry '%s' is already in blacklist", + "commands.blossom.filter.dimension.blacklist.remove": "Removed dimension entry '%s' from blacklist", + "commands.blossom.filter.dimension.blacklist.remove.failed": "Dimension entry '%s' is not in blacklist", "commands.blossom.filter.biome.whitelist.query": "Whitelisted biomes: %s", - "commands.blossom.filter.biome.whitelist.add": "Added biome '%s' to whitelist", - "commands.blossom.filter.biome.whitelist.add.failed": "Biome '%s' is already in whitelist", - "commands.blossom.filter.biome.whitelist.remove": "Removed biome '%s' from whitelist", - "commands.blossom.filter.biome.whitelist.remove.failed": "Biome '%s' is not in whitelist", + "commands.blossom.filter.biome.whitelist.list": "%s", + "commands.blossom.filter.biome.whitelist.list.tooltip": "Biomes that allow blossoming", + "commands.blossom.filter.biome.whitelist.add": "Added biome entry '%s' to whitelist", + "commands.blossom.filter.biome.whitelist.add.failed": "Biome entry '%s' is already in whitelist", + "commands.blossom.filter.biome.whitelist.remove": "Removed biome entry '%s' from whitelist", + "commands.blossom.filter.biome.whitelist.remove.failed": "Biome entry '%s' is not in whitelist", "commands.blossom.filter.biome.blacklist.query": "Blacklisted biomes: %s", - "commands.blossom.filter.biome.blacklist.add": "Added biome '%s' to blacklist", - "commands.blossom.filter.biome.blacklist.add.failed": "Biome '%s' is already in blacklist", - "commands.blossom.filter.biome.blacklist.remove": "Removed biome '%s' from blacklist", - "commands.blossom.filter.biome.blacklist.remove.failed": "Biome '%s' is not in blacklist", + "commands.blossom.filter.biome.blacklist.list": "%s", + "commands.blossom.filter.biome.blacklist.list.tooltip": "Biomes that disallow blossoming", + "commands.blossom.filter.biome.blacklist.add": "Added biome entry '%s' to blacklist", + "commands.blossom.filter.biome.blacklist.add.failed": "Biome entry '%s' is already in blacklist", + "commands.blossom.filter.biome.blacklist.remove": "Removed entry '%s' from blacklist", + "commands.blossom.filter.biome.blacklist.remove.failed": "Biome entry '%s' is not in blacklist", "commands.blossom.toggle.whitelist.query": "Whitelist is currently set to: %s", "commands.blossom.toggle.whitelist.set": "Whitelist is now set to: %s", + "commands.blossom.toggle.whitelist.toggle": "%s", + "commands.blossom.toggle.whitelist.toggle.tooltip": "Whether blossoming is enabled in the whitelisted dimensions and biomes", "commands.blossom.toggle.blacklist.query": "Blacklist is currently set to: %s", - "commands.blossom.toggle.blacklist.set": "Blacklist is now set to: %s" + "commands.blossom.toggle.blacklist.set": "Blacklist is now set to: %s", + "commands.blossom.toggle.blacklist.toggle": "%s", + "commands.blossom.toggle.blacklist.toggle.tooltip": "Whether blossoming is disabled in the blacklisted dimensions and biomes" } \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_leaves.json b/src/main/resources/assets/blossom/models/block/flowering_leaves.json index 4e9697a..b303f7e 100644 --- a/src/main/resources/assets/blossom/models/block/flowering_leaves.json +++ b/src/main/resources/assets/blossom/models/block/flowering_leaves.json @@ -1,29 +1,86 @@ -{ "parent": "block/block", - "textures": { - "particle": "#all" +{ + "parent": "block/block", + "textures": { + "particle": "#all" + }, + "elements": [ + { + "from": [0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "down" + }, + "up": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "up" + }, + "north": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "north" + }, + "south": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "south" + }, + "west": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "west" + }, + "east": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "east" + } + } }, - "elements": [ - { "from": [ 0, 0, 0 ], - "to": [ 16, 16, 16 ], - "faces": { - "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "down" }, - "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "up" }, - "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "north" }, - "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "south" }, - "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "west" }, - "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "east" } - } - }, - { "from": [ 0, 0, 0 ], - "to": [ 16, 16, 16 ], - "faces": { - "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#flowers", "cullface": "down" }, - "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#flowers", "cullface": "up" }, - "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#flowers", "cullface": "north" }, - "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#flowers", "cullface": "south" }, - "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#flowers", "cullface": "west" }, - "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#flowers", "cullface": "east" } - } + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#flowers", + "cullface": "down" + }, + "up": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#flowers", + "cullface": "up" + }, + "north": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#flowers", + "cullface": "north" + }, + "south": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#flowers", + "cullface": "south" + }, + "west": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#flowers", + "cullface": "west" + }, + "east": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#flowers", + "cullface": "east" } - ] + } + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage0.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage0.json index 49c4c6a..d5a63d1 100644 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage0.json +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage0.json @@ -1,7 +1,7 @@ { - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage0" - } + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage0" + } } \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1.json deleted file mode 100644 index 9ba3282..0000000 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage1" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1a.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1a.json new file mode 100644 index 0000000..357e172 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1a.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage1a" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1b.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1b.json new file mode 100644 index 0000000..1e344fb --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1b.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage1b" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1c.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1c.json new file mode 100644 index 0000000..931e138 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage1c.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage1c" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2.json deleted file mode 100644 index 69863bd..0000000 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage2" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2a.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2a.json new file mode 100644 index 0000000..4cfaea8 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2a.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage2a" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2b.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2b.json new file mode 100644 index 0000000..735f4b5 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2b.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage2b" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2c.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2c.json new file mode 100644 index 0000000..d78364b --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2c.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage2c" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2d.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2d.json new file mode 100644 index 0000000..735f4b5 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2d.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage2b" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2e.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2e.json new file mode 100644 index 0000000..4cfaea8 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2e.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage2a" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2f.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2f.json new file mode 100644 index 0000000..735f4b5 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage2f.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage2b" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage3.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage3.json index c4e7e91..eb8d46a 100644 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage3.json +++ b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage3.json @@ -1,7 +1,7 @@ { - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage3" - } + "parent": "blossom:block/flowering_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "flowers": "blossom:block/flowering_oak_leaves_stage3" + } } \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage4.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage4.json deleted file mode 100644 index 012f5ca..0000000 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage4.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage4" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage5.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage5.json deleted file mode 100644 index 35951a5..0000000 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage5.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage5" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage6.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage6.json deleted file mode 100644 index 51d261e..0000000 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage6.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage6" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage7.json b/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage7.json deleted file mode 100644 index 31ef4f3..0000000 --- a/src/main/resources/assets/blossom/models/block/flowering_oak_leaves_stage7.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "blossom:block/flowering_leaves", - "textures": { - "all": "minecraft:block/oak_leaves", - "flowers": "blossom:block/flowering_oak_leaves_stage7" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_leaves.json b/src/main/resources/assets/blossom/models/block/fruiting_leaves.json new file mode 100644 index 0000000..5a0f68d --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_leaves.json @@ -0,0 +1,86 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#all" + }, + "elements": [ + { + "from": [0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "down" + }, + "up": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "up" + }, + "north": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "north" + }, + "south": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "south" + }, + "west": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "west" + }, + "east": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#all", + "tintindex": 0, + "cullface": "east" + } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#fruit", + "cullface": "down" + }, + "up": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#fruit", + "cullface": "up" + }, + "north": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#fruit", + "cullface": "north" + }, + "south": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#fruit", + "cullface": "south" + }, + "west": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#fruit", + "cullface": "west" + }, + "east": { + "uv": [ 0, 0, 16, 16 ], + "texture": "#fruit", + "cullface": "east" + } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage0.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage0.json new file mode 100644 index 0000000..e65e48b --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage0.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage1.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage1.json new file mode 100644 index 0000000..950a8d1 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage1.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage2.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage2.json new file mode 100644 index 0000000..511a77e --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage2.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage3.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage3.json new file mode 100644 index 0000000..664fb09 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage3.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage3" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage4.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage4.json new file mode 100644 index 0000000..dadf4a7 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage4.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage4" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage5.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage5.json new file mode 100644 index 0000000..8693a32 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage5.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage5" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage6.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage6.json new file mode 100644 index 0000000..2d129c9 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage6.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage6" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage7.json b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage7.json new file mode 100644 index 0000000..3802697 --- /dev/null +++ b/src/main/resources/assets/blossom/models/block/fruiting_oak_leaves_stage7.json @@ -0,0 +1,7 @@ +{ + "parent": "blossom:block/fruiting_leaves", + "textures": { + "all": "minecraft:block/oak_leaves", + "fruit": "blossom:block/fruiting_oak_leaves_stage7" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/item/flowering_oak_leaves.json b/src/main/resources/assets/blossom/models/item/flowering_oak_leaves.json index b3ce2ea..e175334 100644 --- a/src/main/resources/assets/blossom/models/item/flowering_oak_leaves.json +++ b/src/main/resources/assets/blossom/models/item/flowering_oak_leaves.json @@ -1,53 +1,29 @@ { - "parent": "blossom:block/flowering_oak_leaves_stage0", - "overrides": [ - { - "predicate": { - "age": 0.000 - }, - "model": "blossom:block/flowering_oak_leaves_stage0" - }, - { - "predicate": { - "age": 0.125 - }, - "model": "blossom:block/flowering_oak_leaves_stage1" - }, - { - "predicate": { - "age": 0.250 - }, - "model": "blossom:block/flowering_oak_leaves_stage2" - }, - { - "predicate": { - "age": 0.375 - }, - "model": "blossom:block/flowering_oak_leaves_stage3" - }, - { - "predicate": { - "age": 0.500 - }, - "model": "blossom:block/flowering_oak_leaves_stage4" - }, - { - "predicate": { - "age": 0.625 - }, - "model": "blossom:block/flowering_oak_leaves_stage5" - }, - { - "predicate": { - "age": 0.750 - }, - "model": "blossom:block/flowering_oak_leaves_stage6" - }, - { - "predicate": { - "age": 0.875 - }, - "model": "blossom:block/flowering_oak_leaves_stage7" - } - ] + "parent": "blossom:block/flowering_oak_leaves_stage3", + "overrides": [ + { + "predicate": { + "age": 0.0 + }, + "model": "blossom:block/flowering_oak_leaves_stage0" + }, + { + "predicate": { + "age": 0.25 + }, + "model": "blossom:block/flowering_oak_leaves_stage1a" + }, + { + "predicate": { + "age": 0.5 + }, + "model": "blossom:block/flowering_oak_leaves_stage2a" + }, + { + "predicate": { + "age": 0.75 + }, + "model": "blossom:block/flowering_oak_leaves_stage3" + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/blossom/models/item/fruiting_oak_leaves.json b/src/main/resources/assets/blossom/models/item/fruiting_oak_leaves.json new file mode 100644 index 0000000..4f10534 --- /dev/null +++ b/src/main/resources/assets/blossom/models/item/fruiting_oak_leaves.json @@ -0,0 +1,53 @@ +{ + "parent": "blossom:block/fruiting_oak_leaves_stage7", + "overrides": [ + { + "predicate": { + "age": 0.000 + }, + "model": "blossom:block/fruiting_oak_leaves_stage0" + }, + { + "predicate": { + "age": 0.125 + }, + "model": "blossom:block/fruiting_oak_leaves_stage1" + }, + { + "predicate": { + "age": 0.250 + }, + "model": "blossom:block/fruiting_oak_leaves_stage2" + }, + { + "predicate": { + "age": 0.375 + }, + "model": "blossom:block/fruiting_oak_leaves_stage3" + }, + { + "predicate": { + "age": 0.500 + }, + "model": "blossom:block/fruiting_oak_leaves_stage4" + }, + { + "predicate": { + "age": 0.625 + }, + "model": "blossom:block/fruiting_oak_leaves_stage5" + }, + { + "predicate": { + "age": 0.750 + }, + "model": "blossom:block/fruiting_oak_leaves_stage6" + }, + { + "predicate": { + "age": 0.875 + }, + "model": "blossom:block/fruiting_oak_leaves_stage7" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/particles/blossom.json b/src/main/resources/assets/blossom/particles/blossom.json new file mode 100644 index 0000000..e2eaea5 --- /dev/null +++ b/src/main/resources/assets/blossom/particles/blossom.json @@ -0,0 +1,16 @@ +{ + "textures": [ + "blossom:blossom_0", + "blossom:blossom_1", + "blossom:blossom_2", + "blossom:blossom_3", + "blossom:blossom_4", + "blossom:blossom_5", + "blossom:blossom_6", + "blossom:blossom_7", + "blossom:blossom_8", + "blossom:blossom_9", + "blossom:blossom_10", + "blossom:blossom_11" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/blossom/shaders/block.properties b/src/main/resources/assets/blossom/shaders/block.properties index 5481d31..14f5dd7 100644 --- a/src/main/resources/assets/blossom/shaders/block.properties +++ b/src/main/resources/assets/blossom/shaders/block.properties @@ -1,2 +1,2 @@ -block.10018 = blossom:flowering_oak_leaves -block.18 = blossom:flowering_oak_leaves \ No newline at end of file +block.10018 = blossom:flowering_oak_leaves blossom:fruiting_oak_leaves +block.18 = blossom:flowering_oak_leaves blossom:fruiting_oak_leaves \ No newline at end of file diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1.png deleted file mode 100644 index 1961c89..0000000 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1.png and /dev/null differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1a.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1a.png new file mode 100644 index 0000000..22b588f Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1a.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1b.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1b.png new file mode 100644 index 0000000..ae5cd1c Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1b.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1c.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1c.png new file mode 100644 index 0000000..5b63d3c Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage1c.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2.png deleted file mode 100644 index 8718bf9..0000000 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2.png and /dev/null differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2a.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2a.png new file mode 100644 index 0000000..6b73b56 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2a.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2b.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2b.png new file mode 100644 index 0000000..bf4709d Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2b.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2c.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2c.png new file mode 100644 index 0000000..c011f30 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage2c.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage3.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage3.png index 173e91e..1961c89 100644 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage3.png and b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage3.png differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage4.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage4.png deleted file mode 100644 index ab392d0..0000000 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage4.png and /dev/null differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage5.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage5.png deleted file mode 100644 index b37dc9f..0000000 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage5.png and /dev/null differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage6.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage6.png deleted file mode 100644 index 841214d..0000000 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage6.png and /dev/null differ diff --git a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage7.png b/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage7.png deleted file mode 100644 index 7ab811e..0000000 Binary files a/src/main/resources/assets/blossom/textures/block/flowering_oak_leaves_stage7.png and /dev/null differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage0.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage0.png new file mode 100644 index 0000000..6bf1975 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage0.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage1.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage1.png new file mode 100644 index 0000000..f35a71b Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage1.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage2.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage2.png new file mode 100644 index 0000000..21d3f64 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage2.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage3.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage3.png new file mode 100644 index 0000000..0fbc624 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage3.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage4.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage4.png new file mode 100644 index 0000000..f18bc6d Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage4.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage5.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage5.png new file mode 100644 index 0000000..ba4bf73 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage5.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage6.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage6.png new file mode 100644 index 0000000..79efd31 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage6.png differ diff --git a/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage7.png b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage7.png new file mode 100644 index 0000000..4e378bf Binary files /dev/null and b/src/main/resources/assets/blossom/textures/block/fruiting_oak_leaves_stage7.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_0.png b/src/main/resources/assets/blossom/textures/particle/blossom_0.png new file mode 100644 index 0000000..9b10f56 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_0.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_1.png b/src/main/resources/assets/blossom/textures/particle/blossom_1.png new file mode 100644 index 0000000..c74a5d3 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_1.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_10.png b/src/main/resources/assets/blossom/textures/particle/blossom_10.png new file mode 100644 index 0000000..4efa930 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_10.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_11.png b/src/main/resources/assets/blossom/textures/particle/blossom_11.png new file mode 100644 index 0000000..6cd1ba2 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_11.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_2.png b/src/main/resources/assets/blossom/textures/particle/blossom_2.png new file mode 100644 index 0000000..dddcb29 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_2.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_3.png b/src/main/resources/assets/blossom/textures/particle/blossom_3.png new file mode 100644 index 0000000..6a77dd5 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_3.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_4.png b/src/main/resources/assets/blossom/textures/particle/blossom_4.png new file mode 100644 index 0000000..1917b37 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_4.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_5.png b/src/main/resources/assets/blossom/textures/particle/blossom_5.png new file mode 100644 index 0000000..0d87abc Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_5.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_6.png b/src/main/resources/assets/blossom/textures/particle/blossom_6.png new file mode 100644 index 0000000..1b4ed8e Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_6.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_7.png b/src/main/resources/assets/blossom/textures/particle/blossom_7.png new file mode 100644 index 0000000..1d09336 Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_7.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_8.png b/src/main/resources/assets/blossom/textures/particle/blossom_8.png new file mode 100644 index 0000000..1e7a2ba Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_8.png differ diff --git a/src/main/resources/assets/blossom/textures/particle/blossom_9.png b/src/main/resources/assets/blossom/textures/particle/blossom_9.png new file mode 100644 index 0000000..bfdc5ec Binary files /dev/null and b/src/main/resources/assets/blossom/textures/particle/blossom_9.png differ diff --git a/src/main/resources/blossom.mixins.json b/src/main/resources/blossom.mixins.json index d0f6979..cbab309 100644 --- a/src/main/resources/blossom.mixins.json +++ b/src/main/resources/blossom.mixins.json @@ -5,13 +5,18 @@ "refmap": "blossom.refmap.json", "compatibilityLevel": "JAVA_17", "mixins": [ + "block.AbstractBlockMixin", + "block.BlocksInvoker", "block.ComposterBlockInvoker", "block.FireBlockInvoker", "block.LeavesBlockMixin", + "entity.EntityAccessor", + "entity.MobEntityAccessor", + "entity.ai.goal.GoalInvoker", "entity.passive.BeeEntityInvoker", "entity.passive.BeeEntityMixin", "entity.passive.BeeEntityMixin$GrowCropsGoalMixin", - "entity.passive.BeeEntityMixin$PollinateGoalMixin", + "entity.passive.BeeEntityMixin$MoveToFlowerGoalMixin", "world.biome.BiomeAccessor" ], "client": [ diff --git a/src/main/resources/data/blossom/loot_tables/blocks/flowering_oak_leaves.json b/src/main/resources/data/blossom/loot_tables/blocks/flowering_oak_leaves.json index a42a085..b31e676 100644 --- a/src/main/resources/data/blossom/loot_tables/blocks/flowering_oak_leaves.json +++ b/src/main/resources/data/blossom/loot_tables/blocks/flowering_oak_leaves.json @@ -147,57 +147,6 @@ } ], "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:match_tool", - "predicate": { - "enchantments": [ - { - "enchantment": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - }, - { - "block": "blossom:flowering_oak_leaves", - "condition": "minecraft:block_state_property", - "properties": { - "age": "7" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ], - "functions": [ - { - "enchantment": "minecraft:fortune", - "formula": "minecraft:binomial_with_bonus_count", - "function": "minecraft:apply_bonus", - "parameters": { - "extra": 3, - "probability": 0.5714286 - } - } - ], - "name": "minecraft:apple" - } - ], - "rolls": 1.0 } ] } \ No newline at end of file diff --git a/src/main/resources/data/blossom/loot_tables/blocks/fruiting_oak_leaves.json b/src/main/resources/data/blossom/loot_tables/blocks/fruiting_oak_leaves.json new file mode 100644 index 0000000..3166a88 --- /dev/null +++ b/src/main/resources/data/blossom/loot_tables/blocks/fruiting_oak_leaves.json @@ -0,0 +1,203 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "enchantments": [ + { + "enchantment": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + ], + "functions": [ + { + "block": "blossom:fruiting_oak_leaves", + "function": "minecraft:copy_state", + "properties": [ + "age" + ] + } + ], + "name": "blossom:fruiting_oak_leaves" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "items": [ + "minecraft:shears" + ], + "enchantment": "minecraft:silk_touch", + "levels": { + "max": 0 + } + } + } + ], + "name": "minecraft:oak_leaves" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "chances": [ + 0.05, + 0.0625, + 0.083333336, + 0.1 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "name": "minecraft:oak_sapling" + } + ] + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:alternative", + "terms": [ + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:match_tool", + "predicate": { + "items": [ + "minecraft:shears" + ] + } + } + }, + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:match_tool", + "predicate": { + "enchantments": [ + { + "enchantment": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "chances": [ + 0.02, + 0.022222223, + 0.025, + 0.033333335, + 0.1 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 2.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + }, + { + "function": "minecraft:explosion_decay" + } + ], + "name": "minecraft:stick" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:match_tool", + "predicate": { + "enchantments": [ + { + "enchantment": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + }, + { + "block": "blossom:fruiting_oak_leaves", + "condition": "minecraft:block_state_property", + "properties": { + "age": "7" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "enchantment": "minecraft:fortune", + "formula": "minecraft:binomial_with_bonus_count", + "function": "minecraft:apply_bonus", + "parameters": { + "extra": 3, + "probability": 0.5714286 + } + } + ], + "name": "minecraft:apple" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/minecraft/tags/blocks/bee_growables.json b/src/main/resources/data/minecraft/tags/blocks/bee_growables.json index fd984c3..943fbdb 100644 --- a/src/main/resources/data/minecraft/tags/blocks/bee_growables.json +++ b/src/main/resources/data/minecraft/tags/blocks/bee_growables.json @@ -1,6 +1,6 @@ { "replace": false, "values": [ - "blossom:flowering_oak_leaves" + "blossom:fruiting_oak_leaves" ] } \ No newline at end of file diff --git a/src/main/resources/data/minecraft/tags/blocks/leaves.json b/src/main/resources/data/minecraft/tags/blocks/leaves.json index fd984c3..26a40a4 100644 --- a/src/main/resources/data/minecraft/tags/blocks/leaves.json +++ b/src/main/resources/data/minecraft/tags/blocks/leaves.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ - "blossom:flowering_oak_leaves" + "blossom:flowering_oak_leaves", + "blossom:fruiting_oak_leaves" ] } \ No newline at end of file diff --git a/src/main/resources/data/minecraft/tags/items/leaves.json b/src/main/resources/data/minecraft/tags/items/leaves.json index fd984c3..26a40a4 100644 --- a/src/main/resources/data/minecraft/tags/items/leaves.json +++ b/src/main/resources/data/minecraft/tags/items/leaves.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ - "blossom:flowering_oak_leaves" + "blossom:flowering_oak_leaves", + "blossom:fruiting_oak_leaves" ] } \ No newline at end of file