From d8400a355296cb91d5c891df4f674007c4742c05 Mon Sep 17 00:00:00 2001 From: paisc Date: Fri, 24 Jan 2025 18:57:36 +0100 Subject: [PATCH] added palm tree added quicksand --- .../blockstates/quicksand_block.json | 7 + .../models/block/quicksand_block.json | 6 + .../models/item/quicksand_block.json | 3 + .../net/voltexstudios/VoltexDesertUpdate.java | 14 +- .../VoltexDesertUpdateClient.java | 5 + .../VoltexDesertUpdateDataGenerator.java | 22 ++ .../net/voltexstudios/blocks/ModBlocks.java | 60 +++++ .../blocks/custom/QuicksandBlock.java | 129 +++++++++++ .../datagen/ModBlockTagProvider.java | 23 ++ .../datagen/ModItemTagProvider.java | 26 +++ .../datagen/ModLootTableProvider.java | 24 ++ .../datagen/ModModelProvider.java | 31 +++ .../entity/custom/VultureEntity.java | 219 ++++++++++++++---- .../net/voltexstudios/item/ModItemGroups.java | 33 +++ .../world/ModConfiguredFeatures.java | 44 ++++ .../world/ModPlacedFeatures.java | 43 ++++ .../world/tree/ModSaplingGenerators.java | 13 ++ .../assets/voltexdesertupdate/lang/en_us.json | 12 +- .../textures/block/palm_leaves.png | Bin 0 -> 391 bytes .../textures/block/palm_log.png | Bin 0 -> 644 bytes .../textures/block/palm_log_top.png | Bin 0 -> 536 bytes .../textures/block/palm_sapling.png | Bin 0 -> 313 bytes .../textures/block/quicksand_block.png | Bin 0 -> 189 bytes .../textures/item/palm_sapling.png | Bin 0 -> 313 bytes .../resources/voltexdesertupdate.mixins.json | 22 +- 25 files changed, 678 insertions(+), 58 deletions(-) create mode 100644 src/main/generated/assets/voltexdesertupdate/blockstates/quicksand_block.json create mode 100644 src/main/generated/assets/voltexdesertupdate/models/block/quicksand_block.json create mode 100644 src/main/generated/assets/voltexdesertupdate/models/item/quicksand_block.json create mode 100644 src/main/java/net/voltexstudios/blocks/ModBlocks.java create mode 100644 src/main/java/net/voltexstudios/blocks/custom/QuicksandBlock.java create mode 100644 src/main/java/net/voltexstudios/datagen/ModBlockTagProvider.java create mode 100644 src/main/java/net/voltexstudios/datagen/ModItemTagProvider.java create mode 100644 src/main/java/net/voltexstudios/datagen/ModLootTableProvider.java create mode 100644 src/main/java/net/voltexstudios/datagen/ModModelProvider.java create mode 100644 src/main/java/net/voltexstudios/item/ModItemGroups.java create mode 100644 src/main/java/net/voltexstudios/world/ModConfiguredFeatures.java create mode 100644 src/main/java/net/voltexstudios/world/ModPlacedFeatures.java create mode 100644 src/main/java/net/voltexstudios/world/tree/ModSaplingGenerators.java create mode 100644 src/main/resources/assets/voltexdesertupdate/textures/block/palm_leaves.png create mode 100644 src/main/resources/assets/voltexdesertupdate/textures/block/palm_log.png create mode 100644 src/main/resources/assets/voltexdesertupdate/textures/block/palm_log_top.png create mode 100644 src/main/resources/assets/voltexdesertupdate/textures/block/palm_sapling.png create mode 100644 src/main/resources/assets/voltexdesertupdate/textures/block/quicksand_block.png create mode 100644 src/main/resources/assets/voltexdesertupdate/textures/item/palm_sapling.png diff --git a/src/main/generated/assets/voltexdesertupdate/blockstates/quicksand_block.json b/src/main/generated/assets/voltexdesertupdate/blockstates/quicksand_block.json new file mode 100644 index 0000000..2553abc --- /dev/null +++ b/src/main/generated/assets/voltexdesertupdate/blockstates/quicksand_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "voltexdesertupdate:block/quicksand_block" + } + } +} \ No newline at end of file diff --git a/src/main/generated/assets/voltexdesertupdate/models/block/quicksand_block.json b/src/main/generated/assets/voltexdesertupdate/models/block/quicksand_block.json new file mode 100644 index 0000000..a98dc2f --- /dev/null +++ b/src/main/generated/assets/voltexdesertupdate/models/block/quicksand_block.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "voltexdesertupdate:block/quicksand_block" + } +} \ No newline at end of file diff --git a/src/main/generated/assets/voltexdesertupdate/models/item/quicksand_block.json b/src/main/generated/assets/voltexdesertupdate/models/item/quicksand_block.json new file mode 100644 index 0000000..3ab44db --- /dev/null +++ b/src/main/generated/assets/voltexdesertupdate/models/item/quicksand_block.json @@ -0,0 +1,3 @@ +{ + "parent": "voltexdesertupdate:block/quicksand_block" +} \ No newline at end of file diff --git a/src/main/java/net/voltexstudios/VoltexDesertUpdate.java b/src/main/java/net/voltexstudios/VoltexDesertUpdate.java index d0dc7de..8c7aa2b 100644 --- a/src/main/java/net/voltexstudios/VoltexDesertUpdate.java +++ b/src/main/java/net/voltexstudios/VoltexDesertUpdate.java @@ -3,8 +3,12 @@ package net.voltexstudios; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; +import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; +import net.minecraft.block.FireBlock; +import net.voltexstudios.blocks.ModBlocks; import net.voltexstudios.entity.ModEntities; import net.voltexstudios.entity.custom.VultureEntity; +import net.voltexstudios.item.ModItemGroups; import net.voltexstudios.item.ModItems; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,12 +21,18 @@ public class VoltexDesertUpdate implements ModInitializer { @Override public void onInitialize() { - LOGGER.info("Hello Fabric world!"); + ModItemGroups.registerItemGroups(); ModItems.registerModItems(); + ModBlocks.registerModBlocks(); ModEntities.registerModEntities(); - FabricDefaultAttributeRegistry.register(ModEntities.VULTURE_ENTITY, VultureEntity.createAttributes()); + FabricDefaultAttributeRegistry.register(ModEntities.VULTURE_ENTITY, VultureEntity.createVultureAttributes()); + + FlammableBlockRegistry.getDefaultInstance().add(ModBlocks.PALM_LOG, 5, 5); + FlammableBlockRegistry.getDefaultInstance().add(ModBlocks.PALM_WOOD, 5, 5); + FlammableBlockRegistry.getDefaultInstance().add(ModBlocks.PALM_PLANKS, 5, 20); + FlammableBlockRegistry.getDefaultInstance().add(ModBlocks.PALM_LEAVES, 30, 60); } } \ No newline at end of file diff --git a/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java b/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java index c4d05d0..1aadabd 100644 --- a/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java +++ b/src/main/java/net/voltexstudios/VoltexDesertUpdateClient.java @@ -1,8 +1,11 @@ package net.voltexstudios; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; +import net.minecraft.client.render.RenderLayer; +import net.voltexstudios.blocks.ModBlocks; import net.voltexstudios.entity.ModEntities; import net.voltexstudios.entity.client.VultureModel; import net.voltexstudios.entity.client.VultureRenderer; @@ -13,6 +16,8 @@ public class VoltexDesertUpdateClient implements ClientModInitializer { public void onInitializeClient() { VoltexDesertUpdate.LOGGER.info("Initializing Desert Update Client"); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.PALM_SAPLING, RenderLayer.getCutout()); + EntityModelLayerRegistry.registerModelLayer(VultureModel.VULTURE, VultureModel::getTexturedModelData); EntityRendererRegistry.register(ModEntities.VULTURE_ENTITY, VultureRenderer::new); } diff --git a/src/main/java/net/voltexstudios/VoltexDesertUpdateDataGenerator.java b/src/main/java/net/voltexstudios/VoltexDesertUpdateDataGenerator.java index 39bb10a..f665ade 100644 --- a/src/main/java/net/voltexstudios/VoltexDesertUpdateDataGenerator.java +++ b/src/main/java/net/voltexstudios/VoltexDesertUpdateDataGenerator.java @@ -2,10 +2,32 @@ package net.voltexstudios; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; +import net.minecraft.registry.RegistryBuilder; +import net.minecraft.registry.RegistryKeys; +import net.voltexstudios.datagen.ModBlockTagProvider; +import net.voltexstudios.datagen.ModItemTagProvider; +import net.voltexstudios.datagen.ModLootTableProvider; +import net.voltexstudios.datagen.ModModelProvider; +import net.voltexstudios.world.ModConfiguredFeatures; +import net.voltexstudios.world.ModPlacedFeatures; public class VoltexDesertUpdateDataGenerator implements DataGeneratorEntrypoint { + @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + FabricDataGenerator.Pack pack = fabricDataGenerator.createPack(); + + pack.addProvider(ModBlockTagProvider::new); + pack.addProvider(ModItemTagProvider::new); + pack.addProvider(ModLootTableProvider::new); + pack.addProvider(ModModelProvider::new); + } + + @Override + public void buildRegistry(RegistryBuilder registryBuilder) { + registryBuilder.addRegistry(RegistryKeys.CONFIGURED_FEATURE, ModConfiguredFeatures::bootstrap); + registryBuilder.addRegistry(RegistryKeys.PLACED_FEATURE, ModPlacedFeatures::bootstrap); + } } diff --git a/src/main/java/net/voltexstudios/blocks/ModBlocks.java b/src/main/java/net/voltexstudios/blocks/ModBlocks.java new file mode 100644 index 0000000..cf454cf --- /dev/null +++ b/src/main/java/net/voltexstudios/blocks/ModBlocks.java @@ -0,0 +1,60 @@ +package net.voltexstudios.blocks; + +import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.minecraft.block.*; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroups; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.util.Identifier; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.blocks.custom.QuicksandBlock; +import net.voltexstudios.world.tree.ModSaplingGenerators; + +public class ModBlocks { + + public static final Block QUICKSAND_BLOCK = registerBlock("quicksand_block", + new QuicksandBlock(AbstractBlock.Settings.copy(Blocks.POWDER_SNOW))); + + public static final Block PALM_LOG = registerBlock("palm_log", + new PillarBlock(AbstractBlock.Settings.copy(Blocks.OAK_LOG))); + public static final Block PALM_WOOD = registerBlock("palm_wood", + new PillarBlock(AbstractBlock.Settings.copy(Blocks.OAK_WOOD))); + public static final Block PALM_PLANKS = registerBlock("palm_planks", + new Block(AbstractBlock.Settings.copy(Blocks.OAK_PLANKS))); + public static final Block PALM_LEAVES = registerBlock("palm_leaves", + new LeavesBlock(AbstractBlock.Settings.copy(Blocks.OAK_LEAVES))); + public static final Block PALM_SAPLING = registerBlock("palm_sapling", + new SaplingBlock(ModSaplingGenerators.PALM, AbstractBlock.Settings.create() + .mapColor(MapColor.PALE_YELLOW) + .noCollision() + .ticksRandomly() + .breakInstantly() + .sounds(BlockSoundGroup.SAND) + .pistonBehavior(PistonBehavior.DESTROY))); + + private static Block registerBlockWithoutBlockItem(String name, Block block) { + return Registry.register(Registries.BLOCK, Identifier.of(VoltexDesertUpdate.MOD_ID, name), block); + } + + private static Block registerBlock(String name, Block block) { + registerBlockItem(name, block); + return Registry.register(Registries.BLOCK, Identifier.of(VoltexDesertUpdate.MOD_ID, name), block); + } + + private static void registerBlockItem(String name, Block block) { + Registry.register(Registries.ITEM, Identifier.of(VoltexDesertUpdate.MOD_ID, name), + new BlockItem(block, new Item.Settings())); + } + + public static void registerModBlocks() { + VoltexDesertUpdate.LOGGER.info("Registering Mod Blocks for " + VoltexDesertUpdate.MOD_ID); + + ItemGroupEvents.modifyEntriesEvent(ItemGroups.BUILDING_BLOCKS).register(entries -> { + + }); + } +} diff --git a/src/main/java/net/voltexstudios/blocks/custom/QuicksandBlock.java b/src/main/java/net/voltexstudios/blocks/custom/QuicksandBlock.java new file mode 100644 index 0000000..3a2db52 --- /dev/null +++ b/src/main/java/net/voltexstudios/blocks/custom/QuicksandBlock.java @@ -0,0 +1,129 @@ +package net.voltexstudios.blocks.custom; + +import com.mojang.serialization.MapCodec; +import net.minecraft.block.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.FallingBlockEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.pathing.NavigationType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.particle.DustParticleEffect; +import net.minecraft.registry.tag.EntityTypeTags; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.random.Random; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.*; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class QuicksandBlock extends Block implements FluidDrainable { + + private static final float DAMAGE = 0.25f; + + public static final MapCodec CODEC = createCodec(PowderSnowBlock::new); + + private static final VoxelShape FALLING_SHAPE = VoxelShapes.cuboid(0.0, 0.0, 0.0, 1.0, 0.8999999761581421, 1.0); + + public QuicksandBlock(Settings settings) { + super(settings); + } + + @Override + protected MapCodec getCodec() { + return CODEC; + } + + protected boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { + return stateFrom.isOf(this) || super.isSideInvisible(state, stateFrom, direction); + } + + protected VoxelShape getCullingShape(BlockState state, BlockView world, BlockPos pos) { + return VoxelShapes.empty(); + } + + protected void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + if (!(entity instanceof LivingEntity) || entity.getBlockStateAtPos().isOf(this)) { + entity.slowMovement(state, new Vec3d(0.8999999761581421, 1.5, 0.8999999761581421)); + + entity.damage(world.getDamageSources().inWall(), DAMAGE); + + if (world.isClient) { + Random random = world.getRandom(); + boolean bl = entity.lastRenderX != entity.getX() || entity.lastRenderZ != entity.getZ(); + if (bl && random.nextBoolean()) { + world.addParticle(new DustParticleEffect(new Vec3d(1.0, 1.0, 1.0).toVector3f(), 1.0F), entity.getX(), pos.getY() + 1, entity.getZ(), (double)(MathHelper.nextBetween(random, -1.0F, 1.0F) * 0.083333336F), 0.05000000074505806, (double)(MathHelper.nextBetween(random, -1.0F, 1.0F) * 0.083333336F)); + } + } + } + } + + public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { + if (!((double)fallDistance < 4.0) && entity instanceof LivingEntity livingEntity) { + LivingEntity.FallSounds fallSounds = livingEntity.getFallSounds(); + SoundEvent soundEvent = (double)fallDistance < 7.0 ? fallSounds.small() : fallSounds.big(); + entity.playSound(soundEvent, 1.0F, 1.0F); + } + } + + protected VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + if (context instanceof EntityShapeContext entityShapeContext) { + Entity entity = entityShapeContext.getEntity(); + if (entity != null) { + if (entity.fallDistance > 2.5F) { + return FALLING_SHAPE; + } + + boolean bl = entity instanceof FallingBlockEntity; + if (bl || canWalkOnQuicksand(entity) && context.isAbove(VoxelShapes.fullCube(), pos, false) && !context.isDescending()) { + return super.getCollisionShape(state, world, pos, context); + } + } + } + + return VoxelShapes.empty(); + } + + protected VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return VoxelShapes.empty(); + } + + public static boolean canWalkOnQuicksand(Entity entity) { + if (entity.getType().isIn(EntityTypeTags.POWDER_SNOW_WALKABLE_MOBS)) { + return true; + } else { + return entity instanceof LivingEntity && ((LivingEntity) entity).getEquippedStack(EquipmentSlot.FEET).isOf(Items.LEATHER_BOOTS); + } + } + + public ItemStack tryDrainFluid(@Nullable PlayerEntity player, WorldAccess world, BlockPos pos, BlockState state) { + world.setBlockState(pos, Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL_AND_REDRAW); + if (!world.isClient()) { + world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state)); + } + + return new ItemStack(Items.POWDER_SNOW_BUCKET); + } + + public Optional getBucketFillSound() { + return Optional.of(SoundEvents.ITEM_BUCKET_FILL_POWDER_SNOW); + } + + protected boolean canPathfindThrough(BlockState state, NavigationType type) { + return true; + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return VoxelShapes.empty(); // Optional: also prevents outline rendering + } +} diff --git a/src/main/java/net/voltexstudios/datagen/ModBlockTagProvider.java b/src/main/java/net/voltexstudios/datagen/ModBlockTagProvider.java new file mode 100644 index 0000000..8b9f88c --- /dev/null +++ b/src/main/java/net/voltexstudios/datagen/ModBlockTagProvider.java @@ -0,0 +1,23 @@ +package net.voltexstudios.datagen; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.BlockTags; +import net.voltexstudios.blocks.ModBlocks; + +import java.util.concurrent.CompletableFuture; + +public class ModBlockTagProvider extends FabricTagProvider.BlockTagProvider { + + public ModBlockTagProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { + getOrCreateTagBuilder(BlockTags.LOGS_THAT_BURN) + .add(ModBlocks.PALM_LOG) + .add(ModBlocks.PALM_WOOD); + } +} diff --git a/src/main/java/net/voltexstudios/datagen/ModItemTagProvider.java b/src/main/java/net/voltexstudios/datagen/ModItemTagProvider.java new file mode 100644 index 0000000..dc5ca48 --- /dev/null +++ b/src/main/java/net/voltexstudios/datagen/ModItemTagProvider.java @@ -0,0 +1,26 @@ +package net.voltexstudios.datagen; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.tag.ItemTags; +import net.voltexstudios.blocks.ModBlocks; + +import java.util.concurrent.CompletableFuture; + +public class ModItemTagProvider extends FabricTagProvider.ItemTagProvider { + + public ModItemTagProvider(FabricDataOutput output, CompletableFuture completableFuture) { + super(output, completableFuture); + } + + @Override + protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) { + getOrCreateTagBuilder(ItemTags.LOGS_THAT_BURN) + .add(ModBlocks.PALM_WOOD.asItem()) + .add(ModBlocks.PALM_LOG.asItem()); + + getOrCreateTagBuilder(ItemTags.PLANKS) + .add(ModBlocks.PALM_PLANKS.asItem()); + } +} diff --git a/src/main/java/net/voltexstudios/datagen/ModLootTableProvider.java b/src/main/java/net/voltexstudios/datagen/ModLootTableProvider.java new file mode 100644 index 0000000..595b96d --- /dev/null +++ b/src/main/java/net/voltexstudios/datagen/ModLootTableProvider.java @@ -0,0 +1,24 @@ +package net.voltexstudios.datagen; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider; +import net.minecraft.registry.RegistryWrapper; +import net.voltexstudios.blocks.ModBlocks; + +import java.util.concurrent.CompletableFuture; + +public class ModLootTableProvider extends FabricBlockLootTableProvider { + + public ModLootTableProvider(FabricDataOutput dataOutput, CompletableFuture registryLookup) { + super(dataOutput, registryLookup); + } + + @Override + public void generate() { + addDrop(ModBlocks.PALM_LOG); + addDrop(ModBlocks.PALM_WOOD); + addDrop(ModBlocks.PALM_PLANKS); + addDrop(ModBlocks.PALM_SAPLING); + addDrop(ModBlocks.PALM_LEAVES, leavesDrops(ModBlocks.PALM_LEAVES, ModBlocks.PALM_SAPLING, 0.0625F)); + } +} diff --git a/src/main/java/net/voltexstudios/datagen/ModModelProvider.java b/src/main/java/net/voltexstudios/datagen/ModModelProvider.java new file mode 100644 index 0000000..4df4b2b --- /dev/null +++ b/src/main/java/net/voltexstudios/datagen/ModModelProvider.java @@ -0,0 +1,31 @@ +package net.voltexstudios.datagen; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; +import net.minecraft.data.client.BlockStateModelGenerator; +import net.minecraft.data.client.ItemModelGenerator; +import net.minecraft.data.client.Models; +import net.minecraft.data.client.TexturedModel; +import net.voltexstudios.blocks.ModBlocks; + +public class ModModelProvider extends FabricModelProvider { + + public ModModelProvider(FabricDataOutput output) { + super(output); + } + + @Override + public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { + blockStateModelGenerator.registerLog(ModBlocks.PALM_LOG).log(ModBlocks.PALM_LOG).wood(ModBlocks.PALM_WOOD); + + blockStateModelGenerator.registerSimpleCubeAll(ModBlocks.QUICKSAND_BLOCK); + blockStateModelGenerator.registerSimpleCubeAll(ModBlocks.PALM_PLANKS); + blockStateModelGenerator.registerSingleton(ModBlocks.PALM_LEAVES, TexturedModel.LEAVES); + blockStateModelGenerator.registerTintableCrossBlockState(ModBlocks.PALM_SAPLING, BlockStateModelGenerator.TintType.NOT_TINTED); + } + + @Override + public void generateItemModels(ItemModelGenerator itemModelGenerator) { + itemModelGenerator.register(ModBlocks.PALM_SAPLING.asItem(), Models.GENERATED); + } +} diff --git a/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java b/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java index 4f9e2b4..bccae83 100644 --- a/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java +++ b/src/main/java/net/voltexstudios/entity/custom/VultureEntity.java @@ -1,74 +1,201 @@ package net.voltexstudios.entity.custom; -import net.minecraft.entity.AnimationState; import net.minecraft.entity.EntityType; -import net.minecraft.entity.ai.goal.LookAroundGoal; -import net.minecraft.entity.ai.goal.LookAtEntityGoal; -import net.minecraft.entity.ai.goal.WanderAroundGoal; +import net.minecraft.entity.ai.TargetPredicate; +import net.minecraft.entity.ai.control.FlightMoveControl; +import net.minecraft.entity.ai.goal.*; +import net.minecraft.entity.ai.pathing.BirdNavigation; +import net.minecraft.entity.ai.pathing.EntityNavigation; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.passive.AnimalEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; +import net.minecraft.entity.mob.HostileEntity; +import net.minecraft.entity.passive.RabbitEntity; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.Heightmap; import net.minecraft.world.World; -import net.voltexstudios.entity.ModEntities; -import org.jetbrains.annotations.Nullable; -public class VultureEntity extends AnimalEntity { +import java.util.EnumSet; +import java.util.Random; - public final AnimationState idleAnimationState = new AnimationState(); - private int idleAnimationTimeout; +public class VultureEntity extends HostileEntity { - public VultureEntity(EntityType entityType, World world) { + private static final double STANDARD_FLIGHT_HEIGHT = 20; + private static final double STANDARD_FLIGHT_SPEED = 1.5; + private static final double FORWARD_SPEED = 0.2; + + public VultureEntity(EntityType entityType, World world) { super(entityType, world); + this.moveControl = new FlightMoveControl(this, 20, true); + } + + @Override + protected EntityNavigation createNavigation(World world) { + BirdNavigation navigation = new BirdNavigation(this, world); + navigation.setCanPathThroughDoors(false); + navigation.setCanSwim(true); + return navigation; } @Override protected void initGoals() { - this.goalSelector.add(0, new WanderAroundGoal(this, 1.0)); - this.goalSelector.add(1, new LookAtEntityGoal(this, PlayerEntity.class, 6.0F)); - this.goalSelector.add(2, new LookAroundGoal(this)); + this.goalSelector.add(1, new SwimGoal(this)); + this.goalSelector.add(2, new RabbitHunterGoal(this)); + this.goalSelector.add(2, new FlyGoal(this, 2 * STANDARD_FLIGHT_SPEED)); + + this.goalSelector.add(3, new LookAroundGoal(this)); + + this.goalSelector.add(4, new ForwardFlightGoal(this)); + this.goalSelector.add(4, new MaintainHeightGoal(this, STANDARD_FLIGHT_HEIGHT)); + + + this.targetSelector.add(2, new ActiveTargetGoal<>(this, RabbitEntity.class, true)); } - private void setupAnimationStates() { - if (this.idleAnimationTimeout <= 0) { - this.idleAnimationTimeout = 40; - this.idleAnimationState.start(this.age); - } else { - --this.idleAnimationTimeout; + private static class ForwardFlightGoal extends Goal { + private final VultureEntity vulture; + + public ForwardFlightGoal(VultureEntity vulture) { + this.vulture = vulture; + this.setControls(EnumSet.of(Goal.Control.MOVE)); + } + + @Override + public boolean canStart() { + return !vulture.isOnGround(); + } + + @Override + public void tick() { + Vec3d rotation = vulture.getRotationVector(); + Vec3d movement = rotation.multiply(FORWARD_SPEED); + + vulture.setVelocity(movement.x, vulture.getVelocity().y, movement.z); + } + } + + private static class MaintainHeightGoal extends Goal { + private final VultureEntity vulture; + private final double targetHeight; + + public MaintainHeightGoal(VultureEntity vulture, double height) { + this.vulture = vulture; + this.targetHeight = height; + } + + @Override + public boolean canStart() { + return true; + } + + @Override + public void tick() { + double currentY = vulture.getY(); + double groundLevel = vulture.getWorld().getTopY(Heightmap.Type.WORLD_SURFACE, vulture.getBlockPos().getX(), vulture.getBlockPos().getZ()); + double desiredY = groundLevel + targetHeight; + + desiredY += new Random().nextDouble() * 5; + + if (Math.abs(currentY - desiredY) > 1.0) { + vulture.getMoveControl().moveTo( + vulture.getX(), + desiredY, + vulture.getZ(), + STANDARD_FLIGHT_SPEED + ); + } } } @Override - public void tick() { - super.tick(); + public void fall(double heightDifference, boolean onGroundIn, net.minecraft.block.BlockState state, net.minecraft.util.math.BlockPos pos) { + // Kein Fallschaden für den Geier + } - if (this.getWorld().isClient()) { - this.setupAnimationStates(); + public static DefaultAttributeContainer.Builder createVultureAttributes() { + return HostileEntity.createHostileAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 20.0) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.3) + .add(EntityAttributes.GENERIC_FLYING_SPEED, STANDARD_FLIGHT_SPEED) + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 4.0); + } + + // Benutzerdefinierte Zielklasse zum Jagen von Hasen + private static class RabbitHunterGoal extends Goal { + private final VultureEntity vulture; + private RabbitEntity targetRabbit; + + public RabbitHunterGoal(VultureEntity vulture) { + this.vulture = vulture; + } + + @Override + public boolean canStart() { + this.targetRabbit = findNearestRabbit(); + return this.targetRabbit != null; + } + + @Override + public void tick() { + if (targetRabbit != null) { + // Luftangriff auf den Hasen + vulture.getNavigation().startMovingTo( + targetRabbit.getX(), + targetRabbit.getY() + 1.5, + targetRabbit.getZ(), + 1.2 + ); + + // Angriff, wenn nah genug + if (vulture.distanceTo(targetRabbit) < 2.0) { + vulture.tryAttack(targetRabbit); + } + } + } + + private RabbitEntity findNearestRabbit() { + return vulture.getWorld().getClosestEntity( + RabbitEntity.class, + TargetPredicate.DEFAULT, + vulture, + vulture.getX(), + vulture.getY(), + vulture.getZ(), + vulture.getBoundingBox().expand(25.0) + ); } } - //TODO alter attributes - public static DefaultAttributeContainer.Builder createAttributes() { - return MobEntity.createMobAttributes() - .add(EntityAttributes.GENERIC_MAX_HEALTH, 10.0) - .add(EntityAttributes.GENERIC_FLYING_SPEED, 1.5F) - .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.6F) - .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 10.0) - .add(EntityAttributes.GENERIC_FOLLOW_RANGE, 48.0); - } + // Benutzerdefinierte Zielklasse für Kreisflugverhalten + private static class CircularFlightGoal extends Goal { + private final VultureEntity vulture; + private double circleX, circleZ; + private double angle = 0; - @Override - public boolean isBreedingItem(ItemStack stack) { - return false; - } + public CircularFlightGoal(VultureEntity vulture) { + this.vulture = vulture; + this.setControls(EnumSet.of(Goal.Control.MOVE)); + } - @Nullable - @Override - public PassiveEntity createChild(ServerWorld world, PassiveEntity entity) { - return ModEntities.VULTURE_ENTITY.create(world); + @Override + public boolean canStart() { + // Kreisflug, wenn nicht auf der Jagd + return !vulture.getNavigation().isIdle(); + } + + @Override + public void tick() { + // Kreisfluglogik + angle += 0.1; + double radius = 5.0; + circleX = vulture.getX() + Math.cos(angle) * radius; + circleZ = vulture.getZ() + Math.sin(angle) * radius; + + vulture.getMoveControl().moveTo( + circleX, + vulture.getY() + 3, + circleZ, + STANDARD_FLIGHT_SPEED + ); + } } } diff --git a/src/main/java/net/voltexstudios/item/ModItemGroups.java b/src/main/java/net/voltexstudios/item/ModItemGroups.java new file mode 100644 index 0000000..184de7d --- /dev/null +++ b/src/main/java/net/voltexstudios/item/ModItemGroups.java @@ -0,0 +1,33 @@ +package net.voltexstudios.item; + +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.blocks.ModBlocks; + +public class ModItemGroups { + + public static final ItemGroup DESERT_UPDATE_GROUP = Registry.register(Registries.ITEM_GROUP, + Identifier.of(VoltexDesertUpdate.MOD_ID, "desert_update"), + FabricItemGroup.builder().icon(() -> new ItemStack(ModItems.DUNE_STAFF)) + .displayName(Text.translatable("itemgroup.voltexdesertupdate.desert_update")) + .entries((displayContext, entries) -> { + entries.add(ModItems.DUNE_STAFF); + + entries.add(ModBlocks.QUICKSAND_BLOCK); + entries.add(ModBlocks.PALM_WOOD); + entries.add(ModBlocks.PALM_PLANKS); + entries.add(ModBlocks.PALM_LEAVES); + entries.add(ModBlocks.PALM_SAPLING); + entries.add(ModBlocks.PALM_LOG); + }).build()); + + public static void registerItemGroups() { + VoltexDesertUpdate.LOGGER.info("Registering Item Groups for " + VoltexDesertUpdate.MOD_ID); + } +} diff --git a/src/main/java/net/voltexstudios/world/ModConfiguredFeatures.java b/src/main/java/net/voltexstudios/world/ModConfiguredFeatures.java new file mode 100644 index 0000000..7bc61da --- /dev/null +++ b/src/main/java/net/voltexstudios/world/ModConfiguredFeatures.java @@ -0,0 +1,44 @@ +package net.voltexstudios.world; + +import net.minecraft.block.Blocks; +import net.minecraft.registry.Registerable; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.intprovider.ConstantIntProvider; +import net.minecraft.util.math.intprovider.UniformIntProvider; +import net.minecraft.world.gen.feature.*; +import net.minecraft.world.gen.feature.size.TwoLayersFeatureSize; +import net.minecraft.world.gen.foliage.AcaciaFoliagePlacer; +import net.minecraft.world.gen.stateprovider.BlockStateProvider; +import net.minecraft.world.gen.trunk.BendingTrunkPlacer; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.blocks.ModBlocks; + +public class ModConfiguredFeatures { + + public static final RegistryKey> PALM_KEY = registerKey("palm"); + + public static void bootstrap(Registerable> context) { + + register(context, PALM_KEY, Feature.TREE, new TreeFeatureConfig.Builder( + BlockStateProvider.of(ModBlocks.PALM_LOG), + new BendingTrunkPlacer(3, 2, 0, 4, UniformIntProvider.create(1, 2)), + BlockStateProvider.of(ModBlocks.PALM_LEAVES), + new AcaciaFoliagePlacer(ConstantIntProvider.create(3), ConstantIntProvider.create(1)), + + new TwoLayersFeatureSize(1, 0, 2)) + .build() + ); + + } + + public static RegistryKey> registerKey(String name) { + return RegistryKey.of(RegistryKeys.CONFIGURED_FEATURE, Identifier.of(VoltexDesertUpdate.MOD_ID, name)); + } + + private static > void register(Registerable> context, + RegistryKey> key, F feature, FC configuration) { + context.register(key, new ConfiguredFeature<>(feature, configuration)); + } +} diff --git a/src/main/java/net/voltexstudios/world/ModPlacedFeatures.java b/src/main/java/net/voltexstudios/world/ModPlacedFeatures.java new file mode 100644 index 0000000..f996908 --- /dev/null +++ b/src/main/java/net/voltexstudios/world/ModPlacedFeatures.java @@ -0,0 +1,43 @@ +package net.voltexstudios.world; + +import net.minecraft.registry.Registerable; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; +import net.minecraft.world.gen.feature.*; +import net.minecraft.world.gen.placementmodifier.*; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.blocks.ModBlocks; + +import java.util.List; + +public class ModPlacedFeatures { + + public static final RegistryKey PALM_PLACED_KEY = registerKey("palm_placed"); + + public static void bootstrap(Registerable context) { + var configuredFeatures = context.getRegistryLookup(RegistryKeys.CONFIGURED_FEATURE); + + + register(context, PALM_PLACED_KEY, configuredFeatures.getOrThrow(ModConfiguredFeatures.PALM_KEY), + VegetationPlacedFeatures.treeModifiersWithWouldSurvive( + PlacedFeatures.createCountExtraModifier(2, 0.1f, 2), ModBlocks.PALM_SAPLING)); + + } + + public static RegistryKey registerKey(String name) { + return RegistryKey.of(RegistryKeys.PLACED_FEATURE, Identifier.of(VoltexDesertUpdate.MOD_ID, name)); + } + + private static void register(Registerable context, RegistryKey key, RegistryEntry> configuration, + List modifiers) { + context.register(key, new PlacedFeature(configuration, List.copyOf(modifiers))); + } + + private static > void register(Registerable context, RegistryKey key, + RegistryEntry> configuration, + PlacementModifier... modifiers) { + register(context, key, configuration, List.of(modifiers)); + } +} diff --git a/src/main/java/net/voltexstudios/world/tree/ModSaplingGenerators.java b/src/main/java/net/voltexstudios/world/tree/ModSaplingGenerators.java new file mode 100644 index 0000000..c6daf90 --- /dev/null +++ b/src/main/java/net/voltexstudios/world/tree/ModSaplingGenerators.java @@ -0,0 +1,13 @@ +package net.voltexstudios.world.tree; + +import net.minecraft.block.SaplingGenerator; +import net.voltexstudios.VoltexDesertUpdate; +import net.voltexstudios.world.ModConfiguredFeatures; + +import java.util.Optional; + +public class ModSaplingGenerators { + + public static final SaplingGenerator PALM = new SaplingGenerator(VoltexDesertUpdate.MOD_ID + ":palm", + Optional.empty(), Optional.of(ModConfiguredFeatures.PALM_KEY), Optional.empty()); +} diff --git a/src/main/resources/assets/voltexdesertupdate/lang/en_us.json b/src/main/resources/assets/voltexdesertupdate/lang/en_us.json index 8caf65a..0f27fb0 100644 --- a/src/main/resources/assets/voltexdesertupdate/lang/en_us.json +++ b/src/main/resources/assets/voltexdesertupdate/lang/en_us.json @@ -1,5 +1,15 @@ { "item.voltexdesertupdate.dune_staff": "Staff of the Dunes", - "entity.voltexdesertupdate.vulture": "Vulture" + "entity.voltexdesertupdate.vulture": "Vulture", + + "itemgroup.voltexdesertupdate.desert_update": "Desert Update", + + "block.voltexdesertupdate.quicksand_block": "Quicksand Block", + "block.voltexdesertupdate.palm_log": "Palm Log", + "block.voltexdesertupdate.palm_wood": "Palm Wood", + "block.voltexdesertupdate.palm_planks": "Palm Planks", + "block.voltexdesertupdate.palm_leaves": "Palm Leaves", + "block.voltexdesertupdate.palm_sapling": "Palm Sapling" + } \ No newline at end of file diff --git a/src/main/resources/assets/voltexdesertupdate/textures/block/palm_leaves.png b/src/main/resources/assets/voltexdesertupdate/textures/block/palm_leaves.png new file mode 100644 index 0000000000000000000000000000000000000000..0f30d36915390141d79d228e3c2bf3fb980c2ada GIT binary patch literal 391 zcmV;20eJq2P)n0)*E*I{_# zG`l;q^Upv3jLjF5^LO1OZ2h_GrHkR$eYx0X|Md0cTvZS0vFfM6Q=4P?Qm5=BiO-z) zf4}-A8QZM(Jpq5rclmC|!?m)n%7=8vU~W{7RDIQG#Aa{fQpi-906luTkrfqTE5@7_ zdz4T*eX;=2M=e@ZTa^LuQ^DSsP;bR8EqK+{3W4X*Flod9waHgD=#X3RqKSPx%BuPX;R5*=YQcY`9Q4l?M?#GKw+q6bOYNd8jEuj`y?nIG-t0D*r(uGU$hxrd& z`VRy}YyCjcTCG}}CQb74^6s7c;o_pGvm2N*XU;hzZeP6sAjSv)01>sOO>Tt{0IYS! z=;M(ULJ$$f7-NiDD*(o5Aw+*z4@w7+QYIx)Ge(uqc;}qzjVyqo0D!S$@BPV{B7{&* zI92WsPrq~kilR_k8=b1Eh=_>tZI7Ss1F*I#iUNSOR!VvA#%c&5grJ_i|L(nCUp~FF z*NZU{(dLy!08&Z-A%v`Ld$-#;H@~yj6Aw1mz4uBfV+=EA5+OuNNh!5@w)O7YkeQWI z8LR*(r2xz|8z~y8)Io2cwRXGT3`>jEON4faNnS%VF=J_vP@oJ1C`;%zWwm zDI)UTYocbOQ9Hjd->@9So$IUCx}q@5zCAacQeft6KuU>-hGR}C2_ZrV#%RUtiKwov z*1A8eVvH%J*`_w8!EF1(nutX%MRnNkvtLkM$CErcj10h4iFJg9tjFGda_ zsJquz@K-&0^13LBEJJI}%>NCjSD%m8mfCN=9y{j%Y;AP#Z*A{(rIb0Vm!A&B!&{f7 zlzG}1Q`fcDdTpuw{KJpTV2sHLW+$k2{)90c(#m4HtZEJkz>AMRiKsm@rIfn3FbiN} zc|5U$Q6=u*>||(O)1I9Ma5OCQtN)f8TT>0C)X}i~1&xkN(gcf|hX4Qo4rN$LW=%~1 eDgXcg2mk;800000(o>TF0000Px$xJg7oR5*=QQcG^zFcch$Pb4i{iR>hZ-J)*M&kcHt?s|-FdZ7ZnN`aoDivR|S zE)1)%9ZR7oij=x|j^Mu4o5#oD%z)y{=Z~jT1)wOdkH^RL`c+w$b^Wwl-h1!8_f=J= zDG^a!Kjrz1cDwTHr#Cp)M9MzCFMt97KtKi*Ns{pK_n#%*-rfNCecCIfc$!jbj5$>& zh9LxQUSwBQRTBfH)VrJe@hpV!dj0mW-y35XKK$JRSgn>cvO4EN2ttTq7=#dy$D{W? z#t1-bO?2KQYb}riAR_Pm&f5?I5via6$YIEP!K+fr&E|o4Pp0zOH$L30#(r}s@2(c3 z)Wu?+jDR_~an3pCxbM0SfJzkrYn!Af3Z+!znzQ><;i8z%7$c?h-UCROfGfu6JI@=O z4|{9dwsDP=l8C6PYVZGJ-5g4lD%;rc5spYoIiDAlBtj{LrX?a{%-Wc)>tc*Em1(VG zj4?*7HEXlh(xp}*#F#ppW*MWlvns~Fwtt9-Z}O1Egb=bxmQ6A|e=h)dIlUf#7+<)I z`%(pIt-t-)j#KB_=`;fnLhQOO&u4w#b7Ji6A6>ZMD!>zYHUIzs4rN$LW=%~1DgXcg a2mk;800000(o>TF0000}1CoT}!z{AU2B*pW8 zGsj=X&Hwi#C(gK3Fi&tb;|Z?)HVMfyE|*UejO1Cvc*0N9=pX+iXG4ZqMfUsl8=TnM z>Ltvak8IqL;B+t5ZARjWM=#E`-Rw(Z@NsllcJ9Bretq-NeRcm19{AAJ*f@JSvksro zZG*pD%I6$fEZ?5}K40Lh!-6mVlOEoC{yf3i#o}h*pMGPpgl$XQZ#MDX+53dA?fyn7 zhE0+;JGr<{1zbzqaX&HcU>3u!|1K>*CGPF{d!)gi_g>4F4;O{o=G*U^G+*fH(-eak zhe?brCc-8U?%saR!pp#5_Pls@VCV;HppW@dBRtc5eHpZXYz`m>flI-YL6oPfpUXO@ GgeCx77Juge literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/voltexdesertupdate/textures/block/quicksand_block.png b/src/main/resources/assets/voltexdesertupdate/textures/block/quicksand_block.png new file mode 100644 index 0000000000000000000000000000000000000000..b03c96babcb261df63c81c921d3c03a51f904b55 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VWef#?K^C!C>-`;TR{Nk%e zrd{0C6@Qh_8Yr9Q>Eaktaf{XAAnzdqfz1woChl^SVOw$j@8#kMhF$-4IA;57liK+E zmYj9P+|aTGFD-Ai-icntvF_j*F2DVo>&#*{Ue9a!RU(nIvUGbP0l+XkKNp4RZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/voltexdesertupdate/textures/item/palm_sapling.png b/src/main/resources/assets/voltexdesertupdate/textures/item/palm_sapling.png new file mode 100644 index 0000000000000000000000000000000000000000..2ac1e85e32c4ce0fcf0573fb320192d48067b83a GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`&pcfmLn>}1CoT}!z{AU2B*pW8 zGsj=X&Hwi#C(gK3Fi&tb;|Z?)HVMfyE|*UejO1Cvc*0N9=pX+iXG4ZqMfUsl8=TnM z>Ltvak8IqL;B+t5ZARjWM=#E`-Rw(Z@NsllcJ9Bretq-NeRcm19{AAJ*f@JSvksro zZG*pD%I6$fEZ?5}K40Lh!-6mVlOEoC{yf3i#o}h*pMGPpgl$XQZ#MDX+53dA?fyn7 zhE0+;JGr<{1zbzqaX&HcU>3u!|1K>*CGPF{d!)gi_g>4F4;O{o=G*U^G+*fH(-eak zhe?brCc-8U?%saR!pp#5_Pls@VCV;HppW@dBRtc5eHpZXYz`m>flI-YL6oPfpUXO@ GgeCx77Juge literal 0 HcmV?d00001 diff --git a/src/main/resources/voltexdesertupdate.mixins.json b/src/main/resources/voltexdesertupdate.mixins.json index abac702..25ae644 100644 --- a/src/main/resources/voltexdesertupdate.mixins.json +++ b/src/main/resources/voltexdesertupdate.mixins.json @@ -1,11 +1,15 @@ { - "required": true, - "package": "net.voltexstudios.mixin", - "compatibilityLevel": "JAVA_21", - "mixins": [ - "ExampleMixin" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "package": "net.voltexstudios.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ExampleMixin", + "LivingEntityAccessor" + ], + "injectors": { + "defaultRequire": 1 + }, + "client": [ + "EntityMixin" + ] } \ No newline at end of file