From 4f83a41fe9705e1b8c1bb3eb517d50aa574cb5f9 Mon Sep 17 00:00:00 2001 From: Eli Gibbs Date: Wed, 17 Jun 2026 14:59:01 -0400 Subject: [PATCH] Start adding cultivator and fish items, and recipe builder adjustments as well is egg block adjustments --- .../jurassicrevived/CommonClientClass.java | 3 + .../cmr/jurassicrevived/block/ModBlocks.java | 13 + .../block/custom/CultivatorBlock.java | 233 +++++++ .../block/custom/EggBlock.java | 40 +- .../block/custom/IncubatedEggBlock.java | 41 +- .../block/entity/ModBlockEntities.java | 7 + .../entity/custom/CultivatorBlockEntity.java | 576 ++++++++++++++++++ .../CultivatorBlockEntityRenderer.java | 205 +++++++ .../compat/CultivatorRecipeCategory.java | 215 +++++++ .../jurassicrevived/compat/JEIJRPlugin.java | 18 + .../compat/MachineJadePlugin.java | 48 ++ .../datagen/ModBlockLootTableProvider.java | 3 + .../datagen/ModBlockStateProvider.java | 7 +- .../datagen/ModBlockTagProvider.java | 6 +- .../datagen/ModEntityLootTableProvider.java | 21 + .../datagen/ModItemModelProvider.java | 21 + .../datagen/ModItemTagProvider.java | 30 +- .../datagen/ModRecipeProvider.java | 18 + .../custom/CultivatingRecipeBuilder.java | 192 ++++++ .../jurassicrevived/entity/ModEntities.java | 3 + .../entity/client/CompsognathusModel.java | 7 + .../entity/custom/AlligatorGarEntity.java | 10 +- .../entity/custom/CoelacanthEntity.java | 8 +- .../entity/custom/MawsoniaEntity.java | 10 +- .../jurassicrevived/item/ModCreativeTabs.java | 23 + .../cmr/jurassicrevived/item/ModItems.java | 22 +- .../mixin/MenuScreensMixin.java | 1 + .../recipe/CultivatorRecipe.java | 244 ++++++++ .../recipe/CultivatorRecipeInput.java | 35 ++ .../recipe/DNAAnalyzerRecipe.java | 10 + .../recipe/DNAExtractorRecipe.java | 10 + .../recipe/DNAHybridizerRecipe.java | 10 + .../EmbryoCalcificationMachineRecipe.java | 10 + .../recipe/EmbryonicMachineRecipe.java | 10 + .../recipe/FossilCleanerRecipe.java | 10 + .../recipe/FossilGrinderRecipe.java | 10 + .../recipe/IncubatorRecipe.java | 10 + .../jurassicrevived/recipe/ModRecipes.java | 10 + .../jurassicrevived/screen/ModMenuTypes.java | 2 + .../screen/custom/CultivatorMenu.java | 146 +++++ .../screen/custom/CultivatorScreen.java | 142 +++++ .../worldgen/ModSpawnDefinitions.java | 5 +- .../assets/jurassicrevived/lang/en_us.json | 26 + .../models/block/cultivator.json | 174 ++++++ .../models/block/cultivator_lit.json | 295 +++++++++ .../models/block/white_cultivator.json | 174 ++++++ .../models/block/white_cultivator_lit.json | 295 +++++++++ .../textures/block/alligator_gar_egg.png | Bin 0 -> 343 bytes .../textures/block/coelacanth_egg.png | Bin 0 -> 366 bytes .../textures/block/cultivator.png | Bin 0 -> 3498 bytes .../textures/block/cultivator_lit.png | Bin 0 -> 3498 bytes .../textures/block/mawsonia_egg.png | Bin 0 -> 363 bytes .../textures/block/white_cultivator.png | Bin 0 -> 3576 bytes .../textures/block/white_cultivator_lit.png | Bin 0 -> 3576 bytes .../textures/entity/compsognathus_rebirth.png | Bin 0 -> 13871 bytes .../textures/item/alligator_gar_dna.png | Bin 0 -> 413 bytes .../item/alligator_gar_skull_fossil.png | Bin 0 -> 587 bytes .../textures/item/alligator_gar_syringe.png | Bin 0 -> 526 bytes .../textures/item/alligator_gar_tissue.png | Bin 0 -> 413 bytes .../textures/item/coelacanth_dna.png | Bin 0 -> 465 bytes .../textures/item/coelacanth_skull_fossil.png | Bin 0 -> 812 bytes .../textures/item/coelacanth_syringe.png | Bin 0 -> 585 bytes .../textures/item/coelacanth_tissue.png | Bin 0 -> 470 bytes .../item/fresh_alligator_gar_skull.png | Bin 0 -> 607 bytes .../textures/item/fresh_coelacanth_skull.png | Bin 0 -> 488 bytes .../textures/item/fresh_mawsonia_skull.png | Bin 0 -> 757 bytes .../textures/item/mawsonia_dna.png | Bin 0 -> 460 bytes .../textures/item/mawsonia_skull_fossil.png | Bin 0 -> 738 bytes .../textures/item/mawsonia_syringe.png | Bin 0 -> 585 bytes .../textures/item/mawsonia_tissue.png | Bin 0 -> 462 bytes .../java/net/cmr/jurassicrevived/JRMod.java | 15 + .../net/cmr/jurassicrevived/JRModClient.java | 7 + 72 files changed, 3407 insertions(+), 24 deletions(-) create mode 100644 common/src/main/java/net/cmr/jurassicrevived/block/custom/CultivatorBlock.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/block/entity/custom/CultivatorBlockEntity.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/block/renderer/CultivatorBlockEntityRenderer.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/compat/CultivatorRecipeCategory.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/datagen/custom/CultivatingRecipeBuilder.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipe.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipeInput.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorMenu.java create mode 100644 common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorScreen.java create mode 100644 common/src/main/resources/assets/jurassicrevived/models/block/cultivator.json create mode 100644 common/src/main/resources/assets/jurassicrevived/models/block/cultivator_lit.json create mode 100644 common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator.json create mode 100644 common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator_lit.json create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/alligator_gar_egg.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/coelacanth_egg.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/cultivator.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/cultivator_lit.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/mawsonia_egg.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator_lit.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/compsognathus_rebirth.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_dna.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_skull_fossil.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_syringe.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_tissue.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_dna.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_skull_fossil.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_syringe.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_tissue.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/fresh_alligator_gar_skull.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/fresh_coelacanth_skull.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/fresh_mawsonia_skull.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_dna.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_skull_fossil.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_syringe.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_tissue.png diff --git a/common/src/main/java/net/cmr/jurassicrevived/CommonClientClass.java b/common/src/main/java/net/cmr/jurassicrevived/CommonClientClass.java index 778ff2a..d3d5267 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/CommonClientClass.java +++ b/common/src/main/java/net/cmr/jurassicrevived/CommonClientClass.java @@ -7,6 +7,7 @@ import dev.architectury.registry.menu.MenuRegistry; import dev.architectury.registry.client.rendering.BlockEntityRendererRegistry; import net.cmr.jurassicrevived.block.ModBlocks; import net.cmr.jurassicrevived.block.entity.ModBlockEntities; +import net.cmr.jurassicrevived.block.renderer.CultivatorBlockEntityRenderer; import net.cmr.jurassicrevived.block.renderer.TankBlockEntityRenderer; import net.cmr.jurassicrevived.entity.ModEntities; import net.cmr.jurassicrevived.entity.client.*; @@ -129,6 +130,7 @@ public class CommonClientClass { LifecycleEvent.SETUP.register(() -> { BlockEntityRendererRegistry.register(ModBlockEntities.TANK_BE.get(), TankBlockEntityRenderer::new); + BlockEntityRendererRegistry.register(ModBlockEntities.CULTIVATOR_BE.get(), CultivatorBlockEntityRenderer::new); }); } @@ -143,6 +145,7 @@ public class CommonClientClass { MenuRegistry.registerScreenFactory(ModMenuTypes.EMBRYONIC_MACHINE_MENU.get(), EmbryonicMachineScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.EMBRYO_CALCIFICATION_MACHINE_MENU.get(), EmbryoCalcificationMachineScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.INCUBATOR_MENU.get(), IncubatorScreen::new); + MenuRegistry.registerScreenFactory(ModMenuTypes.CULTIVATOR_MENU.get(), CultivatorScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.TANK_MENU.get(), TankScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.POWER_CELL_MENU.get(), PowerCellScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.WOOD_CRATE_MENU.get(), CrateScreen::new); diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java b/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java index 24ffd98..b1b9c61 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java +++ b/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java @@ -93,6 +93,8 @@ public class ModBlocks { () -> new EmbryoCalcificationMachineBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_BLACK))); public static final RegistrySupplier INCUBATOR = registerBlock("incubator", () -> new IncubatorBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_BLACK))); + public static final RegistrySupplier CULTIVATOR = registerBlock("cultivator", + () -> new CultivatorBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_BLACK))); public static final RegistrySupplier WHITE_GENERATOR = registerBlock("white_generator", () -> new GeneratorBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_LIGHT_GRAY))); public static final RegistrySupplier WHITE_DNA_EXTRACTOR = registerBlock("white_dna_extractor", @@ -111,6 +113,8 @@ public class ModBlocks { () -> new EmbryoCalcificationMachineBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_LIGHT_GRAY))); public static final RegistrySupplier WHITE_INCUBATOR = registerBlock("white_incubator", () -> new IncubatorBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_LIGHT_GRAY))); + public static final RegistrySupplier WHITE_CULTIVATOR = registerBlock("white_cultivator", + () -> new CultivatorBlock(BlockBehaviour.Properties.of().noOcclusion().requiresCorrectToolForDrops().strength(4f).noLootTable().mapColor(MapColor.COLOR_LIGHT_GRAY))); //? if >1.20.1 { /*public static final RegistrySupplier ROYAL_FERN = registerBlock("royal_fern", @@ -525,6 +529,15 @@ public class ModBlocks { public static final RegistrySupplier MUSSASAURUS_EGG = registerBlock("mussasaurus_egg", () -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.MUSSASAURUS)); + public static final RegistrySupplier COELACANTH_EGG = registerBlock("coelacanth_egg", + () -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.COELACANTH)); + + public static final RegistrySupplier MAWSONIA_EGG = registerBlock("mawsonia_egg", + () -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.MAWSONIA)); + + public static final RegistrySupplier ALLIGATOR_GAR_EGG = registerBlock("alligator_gar_egg", + () -> new EggBlock(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops(), ModEntities.ALLIGATOR_GAR)); + public static final RegistrySupplier INCUBATED_APATOSAURUS_EGG = registerBlock("incubated_apatosaurus_egg", diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/custom/CultivatorBlock.java b/common/src/main/java/net/cmr/jurassicrevived/block/custom/CultivatorBlock.java new file mode 100644 index 0000000..5b9ac1e --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/block/custom/CultivatorBlock.java @@ -0,0 +1,233 @@ +package net.cmr.jurassicrevived.block.custom; + +//? if >1.20.1 { +/*import com.mojang.serialization.MapCodec; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.ItemInteractionResult; +*///?} + +import dev.architectury.registry.menu.MenuRegistry; +import net.cmr.jurassicrevived.block.entity.ModBlockEntities; +import net.cmr.jurassicrevived.block.entity.custom.CultivatorBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ItemParticleOption; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; + +public class CultivatorBlock extends BaseEntityBlock { + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final BooleanProperty LIT = BlockStateProperties.LIT; + + //? if >1.20.1 { + /*public static final MapCodec CODEC = simpleCodec(CultivatorBlock::new); + @Override protected MapCodec codec() { return CODEC; } + *///?} + + public CultivatorBlock(Properties properties) { + super(properties); + } + + private static final VoxelShape SHAPE = Shapes.box( + 0.0 / 16.0, 0.0 / 16.0, 0.0 / 16.0, + 16.0 / 16.0, 32.0 / 16.0, 16.0 / 16.0 + ); + + @Override + public BlockState rotate(BlockState state, Rotation rotation) { + return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); + } + + @Override + public BlockState mirror(BlockState state, Mirror mirror) { + return state.rotate(mirror.getRotation(state.getValue(FACING))); + } + + @Override + public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite().getOpposite()).setValue(LIT, false); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING, LIT); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new CultivatorBlockEntity(blockPos, blockState); + } + + @Override + public RenderShape getRenderShape(BlockState state) { + return RenderShape.MODEL; + } + + @Override + //? if >1.20.1 { + /*public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { + *///?} else { + public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { + //?} + if (!level.isClientSide) { + if (player.getAbilities().instabuild) { + level.removeBlockEntity(pos); + level.setBlock(pos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL); + //? if >1.20.1 { + /*return state; + *///?} else { + return; + //?} + } + + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof CultivatorBlockEntity fbe) { + ItemStack stack = new ItemStack(this.asItem()); + + if (!fbe.isEmptyForDrop()) { + //? if >1.20.1 { + /*CompoundTag tag = fbe.saveWithoutMetadata(level.registryAccess()); + var beTypeKey = level.registryAccess().registryOrThrow(Registries.BLOCK_ENTITY_TYPE).getKey(fbe.getType()); + if (beTypeKey != null) tag.putString("id", beTypeKey.toString()); + stack.set(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(tag)); + *///?} else { + CompoundTag tag = fbe.saveWithoutMetadata(); + stack.getOrCreateTagElement("BlockEntityTag").merge(tag); + //?} + } + + popResource(level, pos, stack); + level.removeBlockEntity(pos); + level.setBlock(pos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL); + //? if >1.20.1 { + /*return state; + *///?} else { + return; + //?} + } + } + super.playerWillDestroy(level, pos, state, player); + //? if >1.20.1 { + /*return state; + *///?} else { + return; + //?} + } + + //? if >1.20.1 { + /*@Override + protected ItemInteractionResult useItemOn(ItemStack pStack, BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHitResult) { + BlockEntity entity = pLevel.getBlockEntity(pPos); + if (entity instanceof CultivatorBlockEntity cultivatorBlockEntity) { + if (!pLevel.isClientSide()) { + if (pStack.is(Items.WATER_BUCKET)) { + long currentAmount = cultivatorBlockEntity.getFluid().getAmount(); + if (16000 - currentAmount >= 1000) { + if (!pPlayer.getAbilities().instabuild) { + pPlayer.setItemInHand(pHand, new ItemStack(Items.BUCKET)); + } + cultivatorBlockEntity.getFluidHandler(null).fill(dev.architectury.fluid.FluidStack.create(net.minecraft.world.level.material.Fluids.WATER, 1000), false); + return ItemInteractionResult.SUCCESS; + } + } + MenuRegistry.openExtendedMenu((ServerPlayer) pPlayer, cultivatorBlockEntity); + } + return ItemInteractionResult.sidedSuccess(pLevel.isClientSide()); + } + return ItemInteractionResult.sidedSuccess(pLevel.isClientSide()); + } + *///?} else { + @Override + public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + BlockEntity entity = level.getBlockEntity(pos); + if (entity instanceof CultivatorBlockEntity cultivatorBlockEntity) { + if (!level.isClientSide()) { + ItemStack stack = player.getItemInHand(hand); + if (stack.is(Items.WATER_BUCKET)) { + long currentAmount = cultivatorBlockEntity.getFluid().getAmount(); + if (16000 - currentAmount >= 1000) { + if (!player.getAbilities().instabuild) { + player.setItemInHand(hand, new ItemStack(Items.BUCKET)); + } + cultivatorBlockEntity.getFluidHandler(null).fill(dev.architectury.fluid.FluidStack.create(net.minecraft.world.level.material.Fluids.WATER, 1000), false); + return InteractionResult.SUCCESS; + } + } + MenuRegistry.openExtendedMenu((ServerPlayer) player, cultivatorBlockEntity); + } + return InteractionResult.sidedSuccess(level.isClientSide()); + } + return InteractionResult.sidedSuccess(level.isClientSide()); + } + //?} + + @Override + public @Nullable BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { + if (blockEntityType != ModBlockEntities.CULTIVATOR_BE.get()) return null; + + if (level.isClientSide) { + return null; + } else { + return createTickerHelper(blockEntityType, ModBlockEntities.CULTIVATOR_BE.get(), + (level1, blockPos, blockState, cultivatorBlockEntity) -> cultivatorBlockEntity.tick(level1, blockPos, blockState)); + } + } + + @Override + public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) { + if (!state.getValue(LIT)) { + return; + } + + double xPos = (double)pos.getX() + 0.5; + double yPos = pos.getY(); + double zPos = (double)pos.getZ() + 0.5; + + Direction direction = state.getValue(FACING).getOpposite(); + Direction.Axis axis = direction.getAxis(); + + double defaultOffset = random.nextDouble() * 0.6 - 0.3; + double xOffsets = axis == Direction.Axis.X ? (double)direction.getStepX() * 0.52 : defaultOffset; + double yOffset = random.nextDouble() * 6.0 / 8.0; + double zOffset = axis == Direction.Axis.Z ? (double)direction.getStepZ() * 0.52 : defaultOffset; + + level.addParticle(ParticleTypes.SMOKE, xPos + xOffsets, yPos + yOffset, zPos + zOffset, 0.0, 0.0, 0.0); + + BlockEntity be = level.getBlockEntity(pos); + if(be instanceof CultivatorBlockEntity cultivatorBlockEntity && !cultivatorBlockEntity.itemHandler.getItem(1).isEmpty()) { + level.addParticle(new ItemParticleOption(ParticleTypes.ITEM, cultivatorBlockEntity.itemHandler.getItem(1)), + xPos + xOffsets, yPos + yOffset, zPos + zOffset, 0.0, 0.0, 0.0); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/custom/EggBlock.java b/common/src/main/java/net/cmr/jurassicrevived/block/custom/EggBlock.java index 0cb4d08..5db4e78 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/block/custom/EggBlock.java +++ b/common/src/main/java/net/cmr/jurassicrevived/block/custom/EggBlock.java @@ -2,6 +2,7 @@ package net.cmr.jurassicrevived.block.custom; import net.cmr.jurassicrevived.block.entity.custom.EggBlockEntity; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; @@ -12,12 +13,20 @@ import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -26,14 +35,43 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Supplier; -public class EggBlock extends Block implements EntityBlock { +public class EggBlock extends Block implements EntityBlock, SimpleWaterloggedBlock { private final Supplier> toSpawn; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; private final int hatchSeconds = 1200; public EggBlock(Properties pProperties, Supplier> toSpawn) { super(pProperties); this.toSpawn = toSpawn; + this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(WATERLOGGED); + } + + @Nullable + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos()); + return this.defaultBlockState().setValue(WATERLOGGED, fluidstate.getType() == Fluids.WATER); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) { + if (state.getValue(WATERLOGGED)) { + level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); + } + return super.updateShape(state, direction, neighborState, level, currentPos, neighborPos); + } + + @Override + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } private static final VoxelShape EGG_SHAPE = Block.box(6.5D, 0.0D, 6.5D, 9.5D, 4.0D, 9.5D); diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/custom/IncubatedEggBlock.java b/common/src/main/java/net/cmr/jurassicrevived/block/custom/IncubatedEggBlock.java index 0436c8e..df07c5b 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/block/custom/IncubatedEggBlock.java +++ b/common/src/main/java/net/cmr/jurassicrevived/block/custom/IncubatedEggBlock.java @@ -2,6 +2,7 @@ package net.cmr.jurassicrevived.block.custom; import net.cmr.jurassicrevived.block.entity.custom.EggBlockEntity; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; @@ -12,12 +13,20 @@ import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -26,14 +35,44 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Supplier; -public class IncubatedEggBlock extends Block implements EntityBlock { +public class IncubatedEggBlock extends Block implements EntityBlock, SimpleWaterloggedBlock +{ private final Supplier> toSpawn; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; private final int hatchSeconds = 60; public IncubatedEggBlock(Properties pProperties, Supplier> toSpawn) { super(pProperties); this.toSpawn = toSpawn; + this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, false)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(WATERLOGGED); + } + + @Nullable + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos()); + return this.defaultBlockState().setValue(WATERLOGGED, fluidstate.getType() == Fluids.WATER); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) { + if (state.getValue(WATERLOGGED)) { + level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); + } + return super.updateShape(state, direction, neighborState, level, currentPos, neighborPos); + } + + @Override + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } private static final VoxelShape EGG_SHAPE = Block.box(6.5D, 0.0D, 6.5D, 9.5D, 4.0D, 9.5D); diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/entity/ModBlockEntities.java b/common/src/main/java/net/cmr/jurassicrevived/block/entity/ModBlockEntities.java index f1958f4..4cfe9c0 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/block/entity/ModBlockEntities.java +++ b/common/src/main/java/net/cmr/jurassicrevived/block/entity/ModBlockEntities.java @@ -109,6 +109,9 @@ public class ModBlockEntities { ModBlocks.CHILESAURUS_EGG.get(), ModBlocks.MUSSASAURUS_EGG.get(), ModBlocks.THESCELOSAURUS_EGG.get(), + ModBlocks.COELACANTH_EGG.get(), + ModBlocks.MAWSONIA_EGG.get(), + ModBlocks.ALLIGATOR_GAR_EGG.get(), ModBlocks.INCUBATED_APATOSAURUS_EGG.get(), ModBlocks.INCUBATED_ALBERTOSAURUS_EGG.get(), ModBlocks.INCUBATED_VELOCIRAPTOR_EGG.get(), @@ -237,6 +240,10 @@ public class ModBlockEntities { BLOCK_ENTITIES.register("incubator_be", () -> BlockEntityType.Builder.of( IncubatorBlockEntity::new, ModBlocks.INCUBATOR.get(), ModBlocks.WHITE_INCUBATOR.get()).build(null)); + public static final RegistrySupplier> CULTIVATOR_BE = + BLOCK_ENTITIES.register("cultivator_be", () -> BlockEntityType.Builder.of( + CultivatorBlockEntity::new, ModBlocks.CULTIVATOR.get(), ModBlocks.WHITE_CULTIVATOR.get()).build(null)); + public static void register() { BLOCK_ENTITIES.register(); } diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/entity/custom/CultivatorBlockEntity.java b/common/src/main/java/net/cmr/jurassicrevived/block/entity/custom/CultivatorBlockEntity.java new file mode 100644 index 0000000..9cfef90 --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/block/entity/custom/CultivatorBlockEntity.java @@ -0,0 +1,576 @@ +package net.cmr.jurassicrevived.block.entity.custom; + +import dev.architectury.fluid.FluidStack; +import dev.architectury.registry.menu.ExtendedMenuProvider; +import net.cmr.jurassicrevived.block.custom.CultivatorBlock; +import net.cmr.jurassicrevived.block.entity.ModBlockEntities; +import net.cmr.jurassicrevived.block.entity.energy.ModEnergyStorage; +import net.cmr.jurassicrevived.block.entity.energy.ModEnergyUtil; +import net.cmr.jurassicrevived.config.JRConfigManager; +import net.cmr.jurassicrevived.platform.transfer.InternalFluidHandler; +import net.cmr.jurassicrevived.platform.transfer.InternalFluidProvider; +import net.cmr.jurassicrevived.recipe.CultivatorRecipe; +import net.cmr.jurassicrevived.recipe.CultivatorRecipeInput; +import net.cmr.jurassicrevived.recipe.ModRecipes; +import net.cmr.jurassicrevived.screen.custom.CultivatorMenu; +import net.cmr.jurassicrevived.util.ModTags; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerData; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.HopperBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +//? if >1.20.1 { +/*import net.minecraft.core.HolderLookup; +import net.minecraft.world.item.crafting.RecipeHolder; +*///?} else { +import net.minecraft.core.RegistryAccess; + //?} + +import java.util.Optional; + +public class CultivatorBlockEntity extends BlockEntity implements ExtendedMenuProvider, ModEnergyUtil.EnergyProvider, InternalFluidProvider +{ + private boolean allowInternalExtraction = false; + + public final SimpleContainer itemHandler = new SimpleContainer(5) { + @Override + public void setChanged() { + super.setChanged(); + CultivatorBlockEntity.this.setChanged(); + if (level != null && !level.isClientSide()) { + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + } + } + + @Override + public boolean canPlaceItem(int slot, ItemStack stack) { + if (slot >= 2 && slot <= 4) return false; + if (slot == WATER_SLOT) { + return stack.is(Items.WATER_BUCKET); + } + if (slot == FOSSILBLOCK_SLOT) return stack.is(net.cmr.jurassicrevived.block.ModBlocks.STONE_FOSSIL.get().asItem()) || stack.is(net.cmr.jurassicrevived.block.ModBlocks.DEEPSLATE_FOSSIL.get().asItem()); + return false; + } + + @Override + public ItemStack removeItem(int slot, int amount) { + if (slot == FOSSILBLOCK_SLOT && !allowInternalExtraction) { + boolean isPlayer = false; + for (StackTraceElement element : Thread.currentThread().getStackTrace()) { + String className = element.getClassName(); + if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) { + isPlayer = true; + break; + } + } + if (!isPlayer) return ItemStack.EMPTY; + } + if (slot == WATER_SLOT && getItem(slot).is(Items.WATER_BUCKET)) { + boolean isPlayer = false; + for (StackTraceElement element : Thread.currentThread().getStackTrace()) { + String className = element.getClassName(); + if (className.contains("inventory") || className.contains("player") || className.contains("ServerGamePacketListenerImpl")) { + isPlayer = true; + break; + } + } + if (!isPlayer) return ItemStack.EMPTY; + } + return super.removeItem(slot, amount); + } + }; + + private static final int WATER_SLOT = 0; + private static final int FOSSILBLOCK_SLOT = 1; + private static final int[] OUTPUT_SLOTS = {2, 3, 4}; + private static final int WATER_CRAFT_AMOUNT = 250; + private static final long TANK_CAPACITY = 16000; + + private FluidStack fluidStack = FluidStack.empty(); + private ItemStack lockedOutput = ItemStack.EMPTY; + private String lastInputSignature = ""; + + private final ContainerData data; + private int progress = 0; + private int maxProgress = 200; + private final int DEFAULT_MAX_PROGRESS = 200; + + private static final int TRANSFER_RATE = 1000; + private final ModEnergyStorage energyStorage = createEnergyStorage(); + + private final InternalFluidHandler fluidHandler = new InternalFluidHandler() { + @Override + public FluidStack getFluid() { + return fluidStack; + } + + @Override + public long getCapacity() { + return TANK_CAPACITY; + } + + @Override + public long fill(FluidStack stack, boolean simulate) { + if (stack.isEmpty()) return 0; + if (!fluidStack.isEmpty() && fluidStack.getFluid() != stack.getFluid()) return 0; + + long space = TANK_CAPACITY - fluidStack.getAmount(); + if (space <= 0) return 0; + + long toFill = Math.min(space, stack.getAmount()); + if (!simulate) { + fluidStack = FluidStack.create(stack.getFluid(), fluidStack.getAmount() + toFill); + setChanged(); + if (level != null && !level.isClientSide()) { + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + } + } + return toFill; + } + + @Override + public FluidStack drain(long amount, boolean simulate) { + if (fluidStack.isEmpty() || amount <= 0) return FluidStack.empty(); + + long drained = Math.min(amount, fluidStack.getAmount()); + FluidStack out = FluidStack.create(fluidStack.getFluid(), drained); + + if (!simulate) { + long remaining = fluidStack.getAmount() - drained; + fluidStack = remaining > 0 + ? FluidStack.create(fluidStack.getFluid(), remaining) + : FluidStack.empty(); + setChanged(); + if (level != null && !level.isClientSide()) { + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + } + } + return out; + } + }; + + @Override + public InternalFluidHandler getFluidHandler(@Nullable Direction side) { + return this.fluidHandler; + } + + public CultivatorBlockEntity(BlockPos pos, BlockState blockState) { + super(ModBlockEntities.CULTIVATOR_BE.get(), pos, blockState); + this.data = new ContainerData() { + @Override + public int get(int pIndex) { + return switch (pIndex) { + case 0 -> CultivatorBlockEntity.this.progress; + case 1 -> CultivatorBlockEntity.this.maxProgress; + default -> 0; + }; + } + + @Override + public void set(int pIndex, int pValue) { + switch (pIndex) { + case 0 -> CultivatorBlockEntity.this.progress = pValue; + case 1 -> CultivatorBlockEntity.this.maxProgress = pValue; + } + } + + @Override + public int getCount() { + return 2; + } + }; + } + + private ModEnergyStorage createEnergyStorage() { + return new ModEnergyStorage(64000, TRANSFER_RATE) { + @Override + public void onEnergyChanged() { + setChanged(); + if (level != null && !level.isClientSide()) { + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + } + } + + @Override + public boolean canExtract() { + return false; + } + + @Override + public int extractEnergy(int maxExtract, boolean simulate) { + return 0; + } + }; + } + + @Override + public ModEnergyStorage getEnergyStorage(@Nullable Direction direction) { + return this.energyStorage; + } + + public FluidStack getFluid() { + return fluidStack; + } + + private void setFluid(FluidStack stack) { + this.fluidStack = stack == null || stack.isEmpty() ? FluidStack.empty() : stack; + setChanged(); + if (level != null && !level.isClientSide()) { + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + } + } + + @Override + public Component getDisplayName() { + return Component.translatable("block.jurassicrevived.cultivator"); + } + + @Override + public void saveExtraData(FriendlyByteBuf buf) { + buf.writeBlockPos(getBlockPos()); + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) { + return new CultivatorMenu(i, inventory, this, this.data); + } + + public boolean isEmptyForDrop() { + return itemHandler.isEmpty() && fluidStack.isEmpty() && progress == 0; + } + + //? if >1.20.1 { + /*@Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.put("Inventory", saveInventory(registries)); + tag.putInt("Prog", this.progress); + tag.putInt("MaxProg", this.maxProgress); + tag.put("Energy", energyStorage.saveNBT()); + if (!fluidStack.isEmpty()) { + tag.put("Fluid", fluidStack.write(registries, new CompoundTag())); + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + loadInventory(tag.getList("Inventory", 10), registries); + progress = tag.getInt("Prog"); + maxProgress = tag.getInt("MaxProg"); + if (tag.contains("Energy")) energyStorage.loadNBT(tag.getCompound("Energy")); + if (tag.contains("Fluid", 10)) { + CompoundTag fluidTag = tag.getCompound("Fluid"); + if (fluidTag.contains("id") && fluidTag.contains("amount")) { + fluidStack = FluidStack.read(registries, fluidTag).orElse(FluidStack.empty()); + } else { + fluidStack = FluidStack.empty(); + } + } else { + fluidStack = FluidStack.empty(); + } + } + + private ListTag saveInventory(HolderLookup.Provider registries) { + ListTag listTag = new ListTag(); + + for (int slot = 0; slot < itemHandler.getContainerSize(); slot++) { + ItemStack stack = itemHandler.getItem(slot); + if (!stack.isEmpty()) { + CompoundTag stackTag = new CompoundTag(); + stackTag.putByte("Slot", (byte) slot); + listTag.add(stack.save(registries, stackTag)); + } + } + + return listTag; + } + + private void loadInventory(ListTag listTag, HolderLookup.Provider registries) { + itemHandler.clearContent(); + + for (int i = 0; i < listTag.size(); i++) { + CompoundTag stackTag = listTag.getCompound(i); + int slot = stackTag.getByte("Slot") & 255; + + if (slot >= 0 && slot < itemHandler.getContainerSize()) { + itemHandler.setItem(slot, ItemStack.parseOptional(registries, stackTag)); + } + } + } + + *///?} else { + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + tag.put("Inventory", saveInventory()); + tag.putInt("Prog", this.progress); + tag.putInt("MaxProg", this.maxProgress); + tag.put("Energy", energyStorage.saveNBT()); + CompoundTag fluidTag = new CompoundTag(); + fluidStack.write(fluidTag); + tag.put("Fluid", fluidTag); + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + loadInventory(tag.getList("Inventory", 10)); + progress = tag.getInt("Prog"); + maxProgress = tag.getInt("MaxProg"); + if (tag.contains("Energy")) energyStorage.loadNBT(tag.getCompound("Energy")); + if (tag.contains("Fluid")) fluidStack = FluidStack.read(tag.getCompound("Fluid")); + } + + private ListTag saveInventory() { + ListTag listTag = new ListTag(); + + for (int slot = 0; slot < itemHandler.getContainerSize(); slot++) { + ItemStack stack = itemHandler.getItem(slot); + if (!stack.isEmpty()) { + CompoundTag stackTag = new CompoundTag(); + stackTag.putByte("Slot", (byte) slot); + stack.save(stackTag); + listTag.add(stackTag); + } + } + + return listTag; + } + + private void loadInventory(ListTag listTag) { + itemHandler.clearContent(); + + for (int i = 0; i < listTag.size(); i++) { + CompoundTag stackTag = listTag.getCompound(i); + int slot = stackTag.getByte("Slot") & 255; + + if (slot >= 0 && slot < itemHandler.getContainerSize()) { + itemHandler.setItem(slot, ItemStack.of(stackTag)); + } + } + } + //?} + + public void tick(Level level, BlockPos pos, BlockState state) { + if (level.isClientSide) return; + + pullEnergyFromNeighbors(); + handleBucketInput(); + pushOutputsToHoppers(); + + //? if >1.20.1 { + /*Optional> recipeOpt = getCurrentRecipe(); + *///?} else { + Optional recipeOpt = getCurrentRecipe(); + //?} + + if (recipeOpt.isEmpty()) { + resetProgress(); + level.setBlockAndUpdate(pos, state.setValue(CultivatorBlock.LIT, false)); + return; + } + + String currentSignature = stackSig(itemHandler.getItem(FOSSILBLOCK_SLOT)); + if (progress == 0 && (lockedOutput.isEmpty() || !currentSignature.equals(lastInputSignature))) { + //? if >1.20.1 { + /*lockedOutput = determineOutput(recipeOpt.get().value()).copy(); + *///?} else { + lockedOutput = determineOutput(recipeOpt.get()).copy(); + //?} + lastInputSignature = currentSignature; + } + + if (!lockedOutput.isEmpty() && canInsertOutput(lockedOutput) && fluidStack.getAmount() >= WATER_CRAFT_AMOUNT) { + if (JRConfigManager.get().requirePower) { + if (energyStorage.getEnergyStored() < 10) return; + energyStorage.extractEnergy(10, false); + } + + progress++; + level.setBlockAndUpdate(pos, state.setValue(CultivatorBlock.LIT, true)); + + if (progress >= maxProgress) { + craftItem(lockedOutput); + fluidStack.setAmount(fluidStack.getAmount() - WATER_CRAFT_AMOUNT); + resetProgress(); + level.setBlockAndUpdate(pos, state.setValue(CultivatorBlock.LIT, false)); + } + } else { + resetProgress(); + level.setBlockAndUpdate(pos, state.setValue(CultivatorBlock.LIT, false)); + } + } + + private void handleBucketInput() { + ItemStack stack = itemHandler.getItem(WATER_SLOT); + if (stack.is(Items.WATER_BUCKET) && (TANK_CAPACITY - fluidStack.getAmount() >= 1000)) { + if (fluidStack.isEmpty() || fluidStack.getFluid().is(FluidTags.WATER)) { + fluidStack = FluidStack.create(net.minecraft.world.level.material.Fluids.WATER, fluidStack.getAmount() + 1000); + itemHandler.setItem(WATER_SLOT, new ItemStack(Items.BUCKET)); + setChanged(); + } + } + } + + private void craftItem(ItemStack output) { + allowInternalExtraction = true; + try { + for (int slot : OUTPUT_SLOTS) { + ItemStack stack = itemHandler.getItem(slot); + if (stack.isEmpty()) { + itemHandler.setItem(slot, output.copy()); + itemHandler.removeItem(FOSSILBLOCK_SLOT, 1); + return; + } else if (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize()) { + stack.grow(output.getCount()); + itemHandler.removeItem(FOSSILBLOCK_SLOT, 1); + return; + } + } + } finally { + allowInternalExtraction = false; + } + } + + private boolean canInsertOutput(ItemStack output) { + for (int slot : OUTPUT_SLOTS) { + ItemStack stack = itemHandler.getItem(slot); + if (stack.isEmpty() || (isSameItem(stack, output) && stack.getCount() + output.getCount() <= stack.getMaxStackSize())) return true; + } + return false; + } + + private boolean isSameItem(ItemStack stack, ItemStack other) { + //? if >1.20.1 { + /*return ItemStack.isSameItemSameComponents(stack, other); + *///?} else { + return ItemStack.isSameItemSameTags(stack, other); + //?} + } + + //? if >1.20.1 { + /*private Optional> getCurrentRecipe() { + return level.getRecipeManager().getRecipeFor(ModRecipes.CULTIVATOR_RECIPE_TYPE.get(), new CultivatorRecipeInput(itemHandler.getItem(FOSSILBLOCK_SLOT), itemHandler.getItem(WATER_SLOT)), level); + } + *///?} else { + private Optional getCurrentRecipe() { + return level.getRecipeManager().getRecipeFor(ModRecipes.CULTIVATOR_RECIPE_TYPE.get(), new CultivatorRecipeInput(itemHandler.getItem(FOSSILBLOCK_SLOT), itemHandler.getItem(WATER_SLOT)), level); + } + //?} + + private ItemStack determineOutput(CultivatorRecipe recipe) { + var registry = level.registryAccess().registryOrThrow(Registries.ITEM); + var tagged = registry.getTag(ModTags.Items.FOSSILS); + + //? if >1.20.1 { + /*ItemStack fallback = recipe.output().copy(); + *///?} else { + ItemStack fallback = recipe.getResultItem(level.registryAccess()).copy(); + //?} + + if (tagged.isEmpty()) return fallback; + + int total = 0; + java.util.List items = new java.util.ArrayList<>(); + java.util.List weights = new java.util.ArrayList<>(); + for (var h : tagged.get()) { + int w = recipe.getWeightFor(h.value()); + if (w > 0) { + items.add(h.value()); + weights.add(w); + total += w; + } + } + if (total <= 0) return fallback; + int roll = level.random.nextInt(total); + int acc = 0; + for (int i = 0; i < items.size(); i++) { + acc += weights.get(i); + if (roll < acc) return new ItemStack(items.get(i), Math.max(1, fallback.getCount())); + } + return fallback; + } + + private String stackSig(ItemStack s) { + return s.isEmpty() ? "empty" : BuiltInRegistries.ITEM.getKey(s.getItem()).toString() + ":" + s.getCount(); + } + + private void resetProgress() { + this.progress = 0; + this.maxProgress = DEFAULT_MAX_PROGRESS; + } + + private void pullEnergyFromNeighbors() { + for (Direction dir : Direction.values()) { + BlockEntity be = level.getBlockEntity(worldPosition.relative(dir)); + if (be instanceof ModEnergyUtil.EnergyProvider provider) { + ModEnergyStorage source = provider.getEnergyStorage(dir.getOpposite()); + if (source != null && source.canExtract()) { + int accepted = energyStorage.receiveEnergy(TRANSFER_RATE, true); + if (accepted > 0) { + energyStorage.receiveEnergy(source.extractEnergy(accepted, false), false); + } + } + } + } + } + + private void pushOutputsToHoppers() { + for (int slot : OUTPUT_SLOTS) { + pushSlotToHoppers(slot); + } + } + + private void pushSlotToHoppers(int slot) { + ItemStack stack = itemHandler.getItem(slot); + if (stack.isEmpty()) return; + + for (Direction dir : Direction.values()) { + BlockEntity be = level.getBlockEntity(worldPosition.relative(dir)); + if (!(be instanceof Container target)) continue; + + ItemStack toMove = stack.copy(); + ItemStack remainder = HopperBlockEntity.addItem(itemHandler, target, toMove, dir); + + if (remainder.getCount() != stack.getCount()) { + itemHandler.setItem(slot, remainder); + setChanged(); + return; + } + } + } + + //? if >1.20.1 { + /*@Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { return saveWithoutMetadata(registries); } + *///?} else { + @Override + public CompoundTag getUpdateTag() { return saveWithoutMetadata(); } + //?} + + @Override + public @Nullable Packet getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } +} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/renderer/CultivatorBlockEntityRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/block/renderer/CultivatorBlockEntityRenderer.java new file mode 100644 index 0000000..d580ce9 --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/block/renderer/CultivatorBlockEntityRenderer.java @@ -0,0 +1,205 @@ +package net.cmr.jurassicrevived.block.renderer; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import dev.architectury.fluid.FluidStack; +import dev.architectury.hooks.fluid.FluidStackHooks; +import net.cmr.jurassicrevived.Constants; +import net.cmr.jurassicrevived.block.entity.custom.CultivatorBlockEntity; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; + +// Credits to TurtyWurty +// Under MIT-License: https://github.com/DaRealTurtyWurty/1.20-Tutorial-Mod?tab=MIT-1-ov-file#readme +public class CultivatorBlockEntityRenderer implements BlockEntityRenderer { + public CultivatorBlockEntityRenderer(BlockEntityRendererProvider.Context context) { + } + + @Override + public void render(CultivatorBlockEntity pBlockEntity, float partialTick, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight, int packedOverlay) { + FluidStack fluidStack = pBlockEntity.getFluid(); + if (fluidStack.isEmpty()) + return; + + Level level = pBlockEntity.getLevel(); + if (level == null) + return; + + TextureAtlasSprite sprite = FluidStackHooks.getStillTexture(fluidStack); + if (isMissing(sprite)) { + sprite = FluidStackHooks.getStillTexture(fluidStack.getFluid()); + } + if (isMissing(sprite)) { + if (fluidStack.getFluid() == Fluids.WATER) { + sprite = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS) + .apply(Constants.r2("block/water_still")); + } + } + + if (isMissing(sprite)) return; + + int tintColor = FluidStackHooks.getColor(fluidStack); + FluidState state = fluidStack.getFluid().defaultFluidState(); + VertexConsumer builder = pBuffer.getBuffer(ItemBlockRenderTypes.getRenderLayer(state)); + + // 1. Adjust bounds for a 2-block tall model + float MIN_Y = 0.125f; // 2 pixels from the bottom + float MAX_Y = 1.875f; // 2 blocks (2.0) minus 2 pixels from the top (0.125) + float MIN_X = 0.1f; + float MAX_X = 0.9f; + float MIN_Z = 0.1f; + float MAX_Z = 0.9f; + + // 2. Calculate actual fluid height + float capacity = 16000f; + float fluidHeight = ((float) fluidStack.getAmount() / capacity) * (MAX_Y - MIN_Y); + float absoluteTop = MIN_Y + fluidHeight; + + // UV coordinates mapping for horizontal planes + float uMin = spriteU(sprite, MIN_X); + float uMax = spriteU(sprite, MAX_X); + float vMinZ = spriteV(sprite, MIN_Z); + float vMaxZ = spriteV(sprite, MAX_Z); + + // 3. Render Top Face (visible from above) + addQuad(builder, pPoseStack, + MIN_X, absoluteTop, MAX_Z, uMin, vMaxZ, + MAX_X, absoluteTop, MAX_Z, uMax, vMaxZ, + MAX_X, absoluteTop, MIN_Z, uMax, vMinZ, + MIN_X, absoluteTop, MIN_Z, uMin, vMinZ, + pPackedLight, tintColor); + + // 4. Render Bottom Face (visible from below) + addQuad(builder, pPoseStack, + MIN_X, MIN_Y, MIN_Z, uMin, vMinZ, + MAX_X, MIN_Y, MIN_Z, uMax, vMinZ, + MAX_X, MIN_Y, MAX_Z, uMax, vMaxZ, + MIN_X, MIN_Y, MAX_Z, uMin, vMaxZ, + pPackedLight, tintColor); + + // 5. Render Sides in 1-block vertical chunks to prevent texture atlas bleeding + int bottomBlock = (int) Math.floor(MIN_Y); + int topBlock = (int) Math.floor(absoluteTop); + + for (int yLevel = bottomBlock; yLevel <= topBlock; yLevel++) { + float chunkMinY = Math.max(MIN_Y, yLevel); + float chunkMaxY = Math.min(absoluteTop, yLevel + 1f); + + if (chunkMinY >= chunkMaxY) continue; // Skip empty chunks + + // Get local block coordinates (0.0 to 1.0) for proper UV mapping + float localMinY = chunkMinY - yLevel; + float localMaxY = chunkMaxY - yLevel; + + float vTop = spriteV(sprite, 1f - localMaxY); + float vBottom = spriteV(sprite, 1f - localMinY); + + // North Face (Z=MIN_Z) + addQuad(builder, pPoseStack, + MAX_X, chunkMaxY, MIN_Z, uMax, vTop, + MAX_X, chunkMinY, MIN_Z, uMax, vBottom, + MIN_X, chunkMinY, MIN_Z, uMin, vBottom, + MIN_X, chunkMaxY, MIN_Z, uMin, vTop, + pPackedLight, tintColor); + + // South Face (Z=MAX_Z) + addQuad(builder, pPoseStack, + MIN_X, chunkMaxY, MAX_Z, uMin, vTop, + MIN_X, chunkMinY, MAX_Z, uMin, vBottom, + MAX_X, chunkMinY, MAX_Z, uMax, vBottom, + MAX_X, chunkMaxY, MAX_Z, uMax, vTop, + pPackedLight, tintColor); + + // West Face (X=MIN_X) + addQuad(builder, pPoseStack, + MIN_X, chunkMaxY, MIN_Z, uMin, vTop, + MIN_X, chunkMinY, MIN_Z, uMin, vBottom, + MIN_X, chunkMinY, MAX_Z, uMax, vBottom, + MIN_X, chunkMaxY, MAX_Z, uMax, vTop, + pPackedLight, tintColor); + + // East Face (X=MAX_X) + addQuad(builder, pPoseStack, + MAX_X, chunkMaxY, MAX_Z, uMax, vTop, + MAX_X, chunkMinY, MAX_Z, uMax, vBottom, + MAX_X, chunkMinY, MIN_Z, uMin, vBottom, + MAX_X, chunkMaxY, MIN_Z, uMin, vTop, + pPackedLight, tintColor); + } + } + + private static boolean isMissing(TextureAtlasSprite sprite) { + return sprite == null || sprite.atlasLocation().getPath().contains("missingno"); + } + + //? if >1.20.1 { + /*private static float spriteU(TextureAtlasSprite sprite, float normalizedU) { + return sprite.getU0() + (sprite.getU1() - sprite.getU0()) * normalizedU; + } + + private static float spriteV(TextureAtlasSprite sprite, float normalizedV) { + return sprite.getV0() + (sprite.getV1() - sprite.getV0()) * normalizedV; + } + *///?} else { + private static float spriteU(TextureAtlasSprite sprite, float normalizedU) { + return sprite.getU(normalizedU * 16); + } + + private static float spriteV(TextureAtlasSprite sprite, float normalizedV) { + return sprite.getV(normalizedV * 16); + } + //?} + + private static void addQuad(VertexConsumer builder, PoseStack poseStack, + float x0, float y0, float z0, float u0, float v0, + float x1, float y1, float z1, float u1, float v1, + float x2, float y2, float z2, float u2, float v2, + float x3, float y3, float z3, float u3, float v3, + int packedLight, int color) { + drawVertex(builder, poseStack, x0, y0, z0, u0, v0, packedLight, color); + drawVertex(builder, poseStack, x1, y1, z1, u1, v1, packedLight, color); + drawVertex(builder, poseStack, x2, y2, z2, u2, v2, packedLight, color); + drawVertex(builder, poseStack, x3, y3, z3, u3, v3, packedLight, color); + } + + //? if >1.20.1 { + /*private static void drawVertex(VertexConsumer builder, PoseStack poseStack, float x, float y, float z, float u, float v, int packedLight, int color) { + int a = (color >> 24) & 0xFF; + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + + if (a == 0) { + a = 255; + } + + builder.addVertex(poseStack.last().pose(), x, y, z) + .setColor(r, g, b, a) + .setUv(u, v) + .setLight(packedLight) + .setNormal(1, 0, 0); + } + *///?} else { + private static void drawVertex(VertexConsumer builder, PoseStack poseStack, float x, float y, float z, float u, float v, int packedLight, int color) { + int a = (color >> 24) & 0xFF; + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = (color) & 0xFF; + + builder.vertex(poseStack.last().pose(), x, y, z) + .color(r, g, b, a) + .uv(u, v) + .uv2(packedLight) + .normal(poseStack.last().normal(), 1, 0, 0) + .endVertex(); + } + //?} +} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/compat/CultivatorRecipeCategory.java b/common/src/main/java/net/cmr/jurassicrevived/compat/CultivatorRecipeCategory.java new file mode 100644 index 0000000..2c7e5bd --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/compat/CultivatorRecipeCategory.java @@ -0,0 +1,215 @@ +package net.cmr.jurassicrevived.compat; + +import dev.architectury.fluid.FluidStack; +import dev.architectury.hooks.fluid.FluidStackHooks; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.builder.IRecipeSlotBuilder; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.category.IRecipeCategory; +import net.cmr.jurassicrevived.Constants; +import net.cmr.jurassicrevived.block.ModBlocks; +import net.cmr.jurassicrevived.config.JRConfigManager; +import net.cmr.jurassicrevived.recipe.CultivatorRecipe; +import net.cmr.jurassicrevived.screen.renderer.FluidTankRenderer; +import net.cmr.jurassicrevived.util.ModTags; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class CultivatorRecipeCategory implements IRecipeCategory { + public static final ResourceLocation UID = Constants.rl("cultivating"); + public static final ResourceLocation TEXTURE = Constants.rl("textures/gui/fossil_cleaner/fossil_cleaner_gui.png"); + private static final ResourceLocation BUBBLES_TEXTURE = Constants.rl("textures/gui/generic/bubbles.png"); + private static final ResourceLocation WHITE_BUBBLES_TEXTURE = Constants.rl("textures/gui/generic/white_bubbles.png"); + private static final ResourceLocation POWER_BAR_TEXTURE = Constants.rl("textures/gui/generic/power_bar.png"); + + public static final RecipeType CULTIVATOR_RECIPE_RECIPE_TYPE = + new RecipeType<>(UID, CultivatorRecipe.class); + + private final IDrawable background; + private final IDrawable icon; + private final FluidTankRenderer fluidRenderer; + private static List WATER_CONTAINERS_CACHE = null; + + public CultivatorRecipeCategory(IGuiHelper guiHelper) { + this.background = guiHelper.drawableBuilder(TEXTURE, 0, 0, 176, 80).setTextureSize(176, 166).build(); + this.icon = guiHelper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(ModBlocks.CULTIVATOR.get())); + this.fluidRenderer = new FluidTankRenderer(64000, true, 16, 50); + if (WATER_CONTAINERS_CACHE == null) { + WATER_CONTAINERS_CACHE = buildWaterContainersList(); + } + } + + @Override + public RecipeType getRecipeType() { + return CULTIVATOR_RECIPE_RECIPE_TYPE; + } + + @Override + public Component getTitle() { + return Component.translatable("block.jurassicrevived.cultivator"); + } + + @Override + public int getWidth() { + return background.getWidth(); + } + + @Override + public int getHeight() { + return background.getHeight(); + } + + @Override + public void draw(CultivatorRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) { + background.draw(guiGraphics); + + FluidStack water = FluidStack.create(Fluids.WATER, 250); + fluidRenderer.render(guiGraphics, 7, 8, water); + + int tankX = 7; + int tankY = 8; + int tankW = fluidRenderer.getWidth(); + int tankH = fluidRenderer.getHeight(); + int mx = (int) mouseX; + int my = (int) mouseY; + if (mx >= tankX && mx < tankX + tankW && my >= tankY && my < tankY + tankH) { + guiGraphics.renderTooltip( + Minecraft.getInstance().font, + fluidRenderer.getTooltip(water, Minecraft.getInstance().options.advancedItemTooltips ? net.minecraft.world.item.TooltipFlag.Default.ADVANCED : net.minecraft.world.item.TooltipFlag.Default.NORMAL), + java.util.Optional.empty(), + mx, + my + ); + } + + guiGraphics.blit(BUBBLES_TEXTURE, 73, 37, 0, 0, 29, 12, 29, 12); + if (JRConfigManager.get().requirePower) { + guiGraphics.blit(POWER_BAR_TEXTURE, 159, 10, 0, 0, 10, 66, 10, 66); + // Fill amount for JEI: show total required energy (2000 FE) relative to 64000 FE capacity + // Our simple fill is purely visual for JEI, not tied to any BE + int barX = 160; + int barY = 11; + int barW = 8; + int barH = 64; + + int maxTicks = 200; + long now = System.currentTimeMillis(); + int progress = (int)((now / 50L) % maxTicks); // ~20 TPS + int arrowPixels = 29; + int progFilled = progress * arrowPixels / maxTicks; + if (progFilled > 0) { + guiGraphics.blit(WHITE_BUBBLES_TEXTURE, 73, 37, 0, 0, progFilled, 12, 29, 12); + } + + int requiredFE = 2000; + int capacityFE = 64000; + int filled = (int)(barH * (requiredFE / (float)capacityFE)); + // Render red fill similar to EnergyDisplayTooltipArea + guiGraphics.fillGradient(barX, barY + (barH - filled), barX + barW, barY + barH, 0xffb51500, 0xff600b00); + + // Tooltip "2000 / 64000 FE" on hover over the energy area + if (mx >= barX && mx < barX + barW && my >= barY && my < barY + barH) { + List tips = List.of(Component.literal("2000 / 64000 FE")); + guiGraphics.renderTooltip(Minecraft.getInstance().font, tips, java.util.Optional.empty(), mx, my); + } + } + } + + @Override + public @Nullable IDrawable getIcon() { + return icon; + } + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, CultivatorRecipe recipe, IFocusGroup focuses) { + + // Single consumable input (fossil block) + builder.addSlot(RecipeIngredientRole.INPUT, 57, 35).addIngredients(recipe.getIngredients().get(0)); + + // Water container acceptance list at (7, 61), discovered dynamically + var waterItems = builder.addSlot(RecipeIngredientRole.INPUT, 7, 61).addItemStacks(WATER_CONTAINERS_CACHE); + waterItems.addRichTooltipCallback((view, tooltip) -> { + tooltip.add(Component.translatable("jurassicrevived.tooltip.accepts_any_water_container")); + }); + + // Output list: all fossils from the tag, tooltip shows per-item weight from the recipe + var level = Minecraft.getInstance().level; + if (level != null) { + var itemRegistry = level.registryAccess().registryOrThrow(Registries.ITEM); + var fossilsTagOpt = itemRegistry.getTag(ModTags.Items.FOSSILS); + List fossilOutputs = fossilsTagOpt.map(holderSet -> + holderSet.stream() + .map(h -> new ItemStack(h.value(), Math.max(1, recipe.output().getCount()))) + .collect(Collectors.toList()) + ).orElse(List.of()); + + // Hide zero-weight fossils + fossilOutputs = fossilOutputs.stream() + .filter(stack -> recipe.getWeightFor(stack.getItem()) > 0) + .collect(Collectors.toList()); + + var slot = builder.addSlot(RecipeIngredientRole.OUTPUT, 103, 35).addItemStacks(fossilOutputs); + slot.addRichTooltipCallback((view, tooltip) -> { + var opt = view.getDisplayedItemStack(); + if (opt.isPresent()) { + int weight = recipe.getWeightFor(opt.get().getItem()); + //tooltip.add(Component.literal("Weight: " + weight)); + } + }); + return; + } + + builder.addSlot(RecipeIngredientRole.OUTPUT, 103, 35).addItemStack(recipe.output()); + } + + private static List buildWaterContainersList() { + var list = new ArrayList(); + // Always include vanilla water bucket (already filled) + list.add(new ItemStack(Items.WATER_BUCKET)); + + var mc = Minecraft.getInstance(); + var level = mc.level; + if (level == null) { + return Collections.unmodifiableList(list); + } + + final int REQUIRED_MB = 250; + + var itemRegistry = level.registryAccess().registryOrThrow(Registries.ITEM); + for (Item item : itemRegistry) { + if (item == Items.WATER_BUCKET) continue; + + ItemStack empty = new ItemStack(item); + // Check if item is a fluid container using Architectury's hooks + // This is a simplified check; a more robust one would involve checking capabilities or similar hooks + // For now, we'll rely on known items or basic checks if available via Architectury + // Since Architectury abstracts this, we might need to rely on platform-specific implementations or common helpers if available. + // However, without a direct common "isFluidContainer" helper in the provided context, we might skip complex checks or use a simple list. + + // For the sake of this conversion, we will stick to just the water bucket as a safe default + // or implement a more complex check if Architectury provides one. + // Given the constraints, we'll simplify this to just water buckets for now to avoid platform-specific code in common. + } + return Collections.unmodifiableList(list); + } +} diff --git a/common/src/main/java/net/cmr/jurassicrevived/compat/JEIJRPlugin.java b/common/src/main/java/net/cmr/jurassicrevived/compat/JEIJRPlugin.java index fb5a01f..d64b36a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/compat/JEIJRPlugin.java +++ b/common/src/main/java/net/cmr/jurassicrevived/compat/JEIJRPlugin.java @@ -52,6 +52,7 @@ public class JEIJRPlugin implements IModPlugin { registration.addRecipeCategories(new EmbryonicMachineRecipeCategory(registration.getJeiHelpers().getGuiHelper())); registration.addRecipeCategories(new EmbryoCalcificationMachineRecipeCategory(registration.getJeiHelpers().getGuiHelper())); registration.addRecipeCategories(new IncubatorRecipeCategory(registration.getJeiHelpers().getGuiHelper())); + registration.addRecipeCategories(new CultivatorRecipeCategory(registration.getJeiHelpers().getGuiHelper())); } @Override @@ -75,6 +76,8 @@ public class JEIJRPlugin implements IModPlugin { .getAllRecipesFor(ModRecipes.EMBRYO_CALCIFICATION_MACHINE_RECIPE_TYPE.get()).stream().map(net.minecraft.world.item.crafting.RecipeHolder::value).toList(); List incubatorRecipes = recipeManager .getAllRecipesFor(ModRecipes.INCUBATOR_RECIPE_TYPE.get()).stream().map(net.minecraft.world.item.crafting.RecipeHolder::value).toList(); + List cultivatorRecipes = recipeManager + .getAllRecipesFor(ModRecipes.CULTIVATOR_RECIPE_TYPE.get()).stream().map(net.minecraft.world.item.crafting.RecipeHolder::value).toList(); *///?} else { List dnaExtractorRecipes = recipeManager.getAllRecipesFor(ModRecipes.DNA_EXTRACTOR_RECIPE_TYPE.get()); List dnaAnalyzerRecipes = recipeManager.getAllRecipesFor(ModRecipes.DNA_ANALYZER_RECIPE_TYPE.get()); @@ -84,6 +87,7 @@ public class JEIJRPlugin implements IModPlugin { List embryonicMachineRecipes = recipeManager.getAllRecipesFor(ModRecipes.EMBRYONIC_MACHINE_RECIPE_TYPE.get()); List embryoCalcificationMachineRecipes = recipeManager.getAllRecipesFor(ModRecipes.EMBRYO_CALCIFICATION_MACHINE_RECIPE_TYPE.get()); List incubatorRecipes = recipeManager.getAllRecipesFor(ModRecipes.INCUBATOR_RECIPE_TYPE.get()); + List cultivatorRecipes = recipeManager.getAllRecipesFor(ModRecipes.CULTIVATOR_RECIPE_TYPE.get()); //?} registration.addRecipes(DNAExtractorRecipeCategory.DNA_EXTRACTOR_RECIPE_RECIPE_TYPE, dnaExtractorRecipes); @@ -94,6 +98,7 @@ public class JEIJRPlugin implements IModPlugin { registration.addRecipes(EmbryonicMachineRecipeCategory.EMBRYONIC_MACHINE_RECIPE_RECIPE_TYPE, embryonicMachineRecipes); registration.addRecipes(EmbryoCalcificationMachineRecipeCategory.EMBRYO_CALCIFICATION_MACHINE_RECIPE_RECIPE_TYPE, embryoCalcificationMachineRecipes); registration.addRecipes(IncubatorRecipeCategory.INCUBATOR_RECIPE_RECIPE_TYPE, incubatorRecipes); + registration.addRecipes(CultivatorRecipeCategory.CULTIVATOR_RECIPE_RECIPE_TYPE, cultivatorRecipes); } @Override @@ -114,6 +119,8 @@ public class JEIJRPlugin implements IModPlugin { EmbryoCalcificationMachineRecipeCategory.EMBRYO_CALCIFICATION_MACHINE_RECIPE_RECIPE_TYPE); registration.addRecipeClickArea(IncubatorScreen.class, 51, 16, 72, 16, IncubatorRecipeCategory.INCUBATOR_RECIPE_RECIPE_TYPE); + registration.addRecipeClickArea(CultivatorScreen.class, 51, 16, 72, 16, + CultivatorRecipeCategory.CULTIVATOR_RECIPE_RECIPE_TYPE); } @Override @@ -126,6 +133,7 @@ public class JEIJRPlugin implements IModPlugin { registration.addRecipeCatalyst(new ItemStack(ModBlocks.EMBRYONIC_MACHINE.get()), EmbryonicMachineRecipeCategory.EMBRYONIC_MACHINE_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get()), EmbryoCalcificationMachineRecipeCategory.EMBRYO_CALCIFICATION_MACHINE_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.INCUBATOR.get()), IncubatorRecipeCategory.INCUBATOR_RECIPE_RECIPE_TYPE); + registration.addRecipeCatalyst(new ItemStack(ModBlocks.CULTIVATOR.get()), CultivatorRecipeCategory.CULTIVATOR_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_DNA_EXTRACTOR.get()), DNAExtractorRecipeCategory.DNA_EXTRACTOR_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_DNA_ANALYZER.get()), DNAAnalyzerRecipeCategory.DNA_ANALYZER_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_FOSSIL_GRINDER.get()), FossilGrinderRecipeCategory.FOSSIL_GRINDER_RECIPE_RECIPE_TYPE); @@ -134,6 +142,7 @@ public class JEIJRPlugin implements IModPlugin { registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_EMBRYONIC_MACHINE.get()), EmbryonicMachineRecipeCategory.EMBRYONIC_MACHINE_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_EMBRYO_CALCIFICATION_MACHINE.get()), EmbryoCalcificationMachineRecipeCategory.EMBRYO_CALCIFICATION_MACHINE_RECIPE_RECIPE_TYPE); registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_INCUBATOR.get()), IncubatorRecipeCategory.INCUBATOR_RECIPE_RECIPE_TYPE); + registration.addRecipeCatalyst(new ItemStack(ModBlocks.WHITE_CULTIVATOR.get()), CultivatorRecipeCategory.CULTIVATOR_RECIPE_RECIPE_TYPE); } @Override @@ -210,5 +219,14 @@ public class JEIJRPlugin implements IModPlugin { 0, // The index where the player inventory slots START (slot 0) 36 // The NUMBER of player inventory slots to check (slots 0-35) ); + registration.addRecipeTransferHandler( + CultivatorMenu.class, + ModMenuTypes.CULTIVATOR_MENU.get(), + CultivatorRecipeCategory.CULTIVATOR_RECIPE_RECIPE_TYPE, + 36, // The index of the FIRST recipe input slot in your Menu (slot 36) + 2, // The NUMBER of recipe input slots (slots 36, 37) + 0, // The index where the player inventory slots START (slot 0) + 36 // The NUMBER of player inventory slots to check (slots 0-35) + ); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/compat/MachineJadePlugin.java b/common/src/main/java/net/cmr/jurassicrevived/compat/MachineJadePlugin.java index 79cf03f..75cb74a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/compat/MachineJadePlugin.java +++ b/common/src/main/java/net/cmr/jurassicrevived/compat/MachineJadePlugin.java @@ -304,6 +304,53 @@ public class MachineJadePlugin implements IWailaPlugin { } }, FossilCleanerBlock.class ); + reg.registerBlockComponent(new snownee.jade.api.IBlockComponentProvider() { + //? if >1.20.1 { + /*@Override + public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) { + CompoundTag data = accessor.getServerData(); + if (data == null || !data.contains(NBT_PROGRESS) || !data.contains(NBT_MAX)) return; + + int progress = Math.max(0, data.getInt(NBT_PROGRESS)); + int max = Math.max(1, data.getInt(NBT_MAX)); + float ratio = Mth.clamp(progress / (float) max, 0.0f, 1.0f); + + IElementHelper h = IElementHelper.get(); + ProgressStyle style = h.progressStyle() + .color(0xFFFFFFFF, 0xFFFFFFFF) + .direction(ScreenDirection.RIGHT) + .fitContentX(true) + .fitContentY(true); + BoxStyle box = BoxStyle.getNestedBox(); + IElement bar = h.progress(ratio, Component.empty(), style, box, true); + tooltip.add(bar); + } + *///?} else { + @Override + public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) { + CompoundTag data = accessor.getServerData(); + if (!data.contains(NBT_PROGRESS) || !data.contains(NBT_MAX)) return; + + int progress = data.getInt(NBT_PROGRESS); + int max = Math.max(1, data.getInt(NBT_MAX)); + float ratio = Mth.clamp(progress / (float) max, 0.0f, 1.0f); + + IElementHelper h = tooltip.getElementHelper(); + IProgressStyle pStyle = h.progressStyle() + .color(0xFFFFFFFF) + .textColor(0xFFFFFFFF); + IBoxStyle box = new ThickBorderBox(1.0f); + + tooltip.add(h.progress(ratio, Component.empty(), pStyle, box, false)); + } + //?} + + @Override + public ResourceLocation getUid() { + return UID; + } + }, CultivatorBlock.class + ); reg.registerBlockComponent(new snownee.jade.api.IBlockComponentProvider() { //? if >1.20.1 { /*@Override @@ -469,5 +516,6 @@ public class MachineJadePlugin implements IWailaPlugin { reg.registerBlockDataProvider(provider, FossilCleanerBlockEntity.class); reg.registerBlockDataProvider(provider, FossilGrinderBlockEntity.class); reg.registerBlockDataProvider(provider, IncubatorBlockEntity.class); + reg.registerBlockDataProvider(provider, CultivatorBlockEntity.class); } } \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java index bee7370..3cf8de9 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java @@ -159,6 +159,9 @@ public class ModBlockLootTableProvider { helper.dropSelf(ModBlocks.CHILESAURUS_EGG.get()); helper.dropSelf(ModBlocks.MUSSASAURUS_EGG.get()); helper.dropSelf(ModBlocks.THESCELOSAURUS_EGG.get()); + helper.dropSelf(ModBlocks.COELACANTH_EGG.get()); + helper.dropSelf(ModBlocks.MAWSONIA_EGG.get()); + helper.dropSelf(ModBlocks.ALLIGATOR_GAR_EGG.get()); helper.dropSelf(ModBlocks.INCUBATED_APATOSAURUS_EGG.get()); helper.dropSelf(ModBlocks.INCUBATED_ALBERTOSAURUS_EGG.get()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java index ef1d9c3..4845c00 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java @@ -181,7 +181,8 @@ public class ModBlockStateProvider { helper.horizontalFacingLitNoBlockstateWithItem(ModBlocks.EMBRYONIC_MACHINE.get()); helper.horizontalFacingLitNoBlockstateWithItem(ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get()); helper.horizontalFacingLitWithItem(ModBlocks.INCUBATOR.get()); - + helper.horizontalFacingLitWithItem(ModBlocks.CULTIVATOR.get()); + helper.horizontalFacingLitWithItem(ModBlocks.WHITE_GENERATOR.get()); helper.horizontalFacingLitNoBlockstateWithItem(ModBlocks.WHITE_DNA_EXTRACTOR.get()); helper.horizontalFacingLitNoBlockstateWithItem(ModBlocks.WHITE_DNA_ANALYZER.get()); @@ -191,6 +192,7 @@ public class ModBlockStateProvider { helper.horizontalFacingLitNoBlockstateWithItem(ModBlocks.WHITE_EMBRYONIC_MACHINE.get()); helper.horizontalFacingLitNoBlockstateWithItem(ModBlocks.WHITE_EMBRYO_CALCIFICATION_MACHINE.get()); helper.horizontalFacingLitWithItem(ModBlocks.WHITE_INCUBATOR.get()); + helper.horizontalFacingLitWithItem(ModBlocks.WHITE_CULTIVATOR.get()); helper.eggLike(ModBlocks.VELOCIRAPTOR_EGG.get()); helper.eggLike(ModBlocks.TYRANNOSAURUS_REX_EGG.get()); @@ -270,6 +272,9 @@ public class ModBlockStateProvider { helper.eggLike(ModBlocks.CHILESAURUS_EGG.get()); helper.eggLike(ModBlocks.MUSSASAURUS_EGG.get()); helper.eggLike(ModBlocks.THESCELOSAURUS_EGG.get()); + helper.eggLike(ModBlocks.COELACANTH_EGG.get()); + helper.eggLike(ModBlocks.MAWSONIA_EGG.get()); + helper.eggLike(ModBlocks.ALLIGATOR_GAR_EGG.get()); helper.eggLike(ModBlocks.INCUBATED_VELOCIRAPTOR_EGG.get()); helper.eggLike(ModBlocks.INCUBATED_TYRANNOSAURUS_REX_EGG.get()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java index ad11be8..c31fbbb 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java @@ -76,6 +76,7 @@ public class ModBlockTagProvider { ModBlocks.EMBRYONIC_MACHINE.get(), ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get(), ModBlocks.INCUBATOR.get(), + ModBlocks.CULTIVATOR.get(), ModBlocks.WHITE_GENERATOR.get(), ModBlocks.WHITE_DNA_EXTRACTOR.get(), ModBlocks.WHITE_DNA_ANALYZER.get(), @@ -85,6 +86,7 @@ public class ModBlockTagProvider { ModBlocks.WHITE_EMBRYONIC_MACHINE.get(), ModBlocks.WHITE_EMBRYO_CALCIFICATION_MACHINE.get(), ModBlocks.WHITE_INCUBATOR.get(), + ModBlocks.WHITE_CULTIVATOR.get(), ModBlocks.TANK.get(), ModBlocks.POWER_CELL.get(), ModBlocks.IRON_CRATE.get() @@ -170,7 +172,9 @@ public class ModBlockTagProvider { ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get(), ModBlocks.INCUBATED_ACHILLOBATOR_EGG.get(), ModBlocks.INCUBATED_SUCHOMIMUS_EGG.get(), - ModBlocks.INCUBATED_CHILESAURUS_EGG.get() + ModBlocks.INCUBATED_CHILESAURUS_EGG.get(), + ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get(), + ModBlocks.INCUBATED_MUSSASAURUS_EGG.get() ); helper.tag(BlockTags.MINEABLE_WITH_SHOVEL, diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModEntityLootTableProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModEntityLootTableProvider.java index ba88412..46d73d9 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModEntityLootTableProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModEntityLootTableProvider.java @@ -531,5 +531,26 @@ public class ModEntityLootTableProvider { .add(LootItem.lootTableItem(ModItems.FRESH_THESCELOSAURUS_SKULL.get())) ) ); + + helper.add(ModEntities.COELACANTH.get(), LootTable.lootTable() + .withPool(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add(LootItem.lootTableItem(ModItems.FRESH_COELACANTH_SKULL.get())) + ) + ); + + helper.add(ModEntities.MAWSONIA.get(), LootTable.lootTable() + .withPool(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add(LootItem.lootTableItem(ModItems.FRESH_MAWSONIA_SKULL.get())) + ) + ); + + helper.add(ModEntities.ALLIGATOR_GAR.get(), LootTable.lootTable() + .withPool(LootPool.lootPool() + .setRolls(ConstantValue.exactly(1)) + .add(LootItem.lootTableItem(ModItems.FRESH_ALLIGATOR_GAR_SKULL.get())) + ) + ); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java index 06bb203..06d3ad9 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java @@ -100,6 +100,9 @@ public class ModItemModelProvider { helper.spawnEgg(ModItems.CHILESAURUS_SPAWN_EGG.get()); helper.spawnEgg(ModItems.THESCELOSAURUS_SPAWN_EGG.get()); helper.spawnEgg(ModItems.MUSSASAURUS_SPAWN_EGG.get()); + helper.spawnEgg(ModItems.COELACANTH_SPAWN_EGG.get()); + helper.spawnEgg(ModItems.MAWSONIA_SPAWN_EGG.get()); + helper.spawnEgg(ModItems.ALLIGATOR_GAR_SPAWN_EGG.get()); helper.basicItemModel(ModItems.FROG_MATERIAL.get()); helper.basicItemModel(ModItems.FROG_DNA.get()); @@ -196,6 +199,9 @@ public class ModItemModelProvider { helper.basicItemModel(ModItems.CHILESAURUS_SKULL_FOSSIL.get()); helper.basicItemModel(ModItems.THESCELOSAURUS_SKULL_FOSSIL.get()); helper.basicItemModel(ModItems.MUSSASAURUS_SKULL_FOSSIL.get()); + helper.basicItemModel(ModItems.COELACANTH_SKULL_FOSSIL.get()); + helper.basicItemModel(ModItems.MAWSONIA_SKULL_FOSSIL.get()); + helper.basicItemModel(ModItems.ALLIGATOR_GAR_SKULL_FOSSIL.get()); helper.basicItemModel(ModItems.FRESH_APATOSAURUS_SKULL.get()); helper.basicItemModel(ModItems.FRESH_ALBERTOSAURUS_SKULL.get()); @@ -275,6 +281,9 @@ public class ModItemModelProvider { helper.basicItemModel(ModItems.FRESH_CHILESAURUS_SKULL.get()); helper.basicItemModel(ModItems.FRESH_THESCELOSAURUS_SKULL.get()); helper.basicItemModel(ModItems.FRESH_MUSSASAURUS_SKULL.get()); + helper.basicItemModel(ModItems.FRESH_COELACANTH_SKULL.get()); + helper.basicItemModel(ModItems.FRESH_MAWSONIA_SKULL.get()); + helper.basicItemModel(ModItems.FRESH_ALLIGATOR_GAR_SKULL.get()); helper.basicItemModel(ModItems.APATOSAURUS_TISSUE.get()); helper.basicItemModel(ModItems.ALBERTOSAURUS_TISSUE.get()); @@ -354,6 +363,9 @@ public class ModItemModelProvider { helper.basicItemModel(ModItems.CHILESAURUS_TISSUE.get()); helper.basicItemModel(ModItems.THESCELOSAURUS_TISSUE.get()); helper.basicItemModel(ModItems.MUSSASAURUS_TISSUE.get()); + helper.basicItemModel(ModItems.COELACANTH_TISSUE.get()); + helper.basicItemModel(ModItems.MAWSONIA_TISSUE.get()); + helper.basicItemModel(ModItems.ALLIGATOR_GAR_TISSUE.get()); helper.basicItemModel(ModItems.APATOSAURUS_DNA.get()); helper.basicItemModel(ModItems.ALBERTOSAURUS_DNA.get()); @@ -433,6 +445,9 @@ public class ModItemModelProvider { helper.basicItemModel(ModItems.CHILESAURUS_DNA.get()); helper.basicItemModel(ModItems.THESCELOSAURUS_DNA.get()); helper.basicItemModel(ModItems.MUSSASAURUS_DNA.get()); + helper.basicItemModel(ModItems.COELACANTH_DNA.get()); + helper.basicItemModel(ModItems.MAWSONIA_DNA.get()); + helper.basicItemModel(ModItems.ALLIGATOR_GAR_DNA.get()); helper.basicItemModel(ModItems.APATOSAURUS_SYRINGE.get()); helper.basicItemModel(ModItems.ALBERTOSAURUS_SYRINGE.get()); @@ -512,6 +527,9 @@ public class ModItemModelProvider { helper.basicItemModel(ModItems.CHILESAURUS_SYRINGE.get()); helper.basicItemModel(ModItems.THESCELOSAURUS_SYRINGE.get()); helper.basicItemModel(ModItems.MUSSASAURUS_SYRINGE.get()); + helper.basicItemModel(ModItems.COELACANTH_SYRINGE.get()); + helper.basicItemModel(ModItems.MAWSONIA_SYRINGE.get()); + helper.basicItemModel(ModItems.ALLIGATOR_GAR_SYRINGE.get()); helper.simpleBlockItemModel(ModBlocks.APATOSAURUS_EGG.get()); helper.simpleBlockItemModel(ModBlocks.ALBERTOSAURUS_EGG.get()); @@ -591,6 +609,9 @@ public class ModItemModelProvider { helper.simpleBlockItemModel(ModBlocks.CHILESAURUS_EGG.get()); helper.simpleBlockItemModel(ModBlocks.THESCELOSAURUS_EGG.get()); helper.simpleBlockItemModel(ModBlocks.MUSSASAURUS_EGG.get()); + helper.simpleBlockItemModel(ModBlocks.COELACANTH_EGG.get()); + helper.simpleBlockItemModel(ModBlocks.MAWSONIA_EGG.get()); + helper.simpleBlockItemModel(ModBlocks.ALLIGATOR_GAR_EGG.get()); helper.basicItemModel(ModBlocks.LOW_SECURITY_FENCE_POLE.get().asItem()); helper.basicItemModel(ModBlocks.LOW_SECURITY_FENCE_WIRE.get().asItem()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemTagProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemTagProvider.java index 1ad79d2..56fe7a6 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemTagProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemTagProvider.java @@ -92,7 +92,10 @@ public class ModItemTagProvider { ModItems.SUCHOMIMUS_TISSUE.get(), ModItems.MUSSASAURUS_TISSUE.get(), ModItems.THESCELOSAURUS_TISSUE.get(), - ModItems.CHILESAURUS_TISSUE.get() + ModItems.CHILESAURUS_TISSUE.get(), + ModItems.COELACANTH_TISSUE.get(), + ModItems.MAWSONIA_TISSUE.get(), + ModItems.ALLIGATOR_GAR_TISSUE.get() ); helper.tag(ModTags.Items.DNA, @@ -174,7 +177,10 @@ public class ModItemTagProvider { ModItems.SUCHOMIMUS_DNA.get(), ModItems.MUSSASAURUS_DNA.get(), ModItems.THESCELOSAURUS_DNA.get(), - ModItems.CHILESAURUS_DNA.get() + ModItems.CHILESAURUS_DNA.get(), + ModItems.COELACANTH_DNA.get(), + ModItems.MAWSONIA_DNA.get(), + ModItems.ALLIGATOR_GAR_DNA.get() ); helper.tag(ModTags.Items.SYRINGES, @@ -256,7 +262,10 @@ public class ModItemTagProvider { ModItems.SUCHOMIMUS_SYRINGE.get(), ModItems.MUSSASAURUS_SYRINGE.get(), ModItems.THESCELOSAURUS_SYRINGE.get(), - ModItems.CHILESAURUS_SYRINGE.get() + ModItems.CHILESAURUS_SYRINGE.get(), + ModItems.COELACANTH_SYRINGE.get(), + ModItems.MAWSONIA_SYRINGE.get(), + ModItems.ALLIGATOR_GAR_SYRINGE.get() ); helper.tag(ModTags.Items.EGGS, @@ -337,7 +346,10 @@ public class ModItemTagProvider { Item.byBlock(ModBlocks.SUCHOMIMUS_EGG.get()), Item.byBlock(ModBlocks.MUSSASAURUS_EGG.get()), Item.byBlock(ModBlocks.THESCELOSAURUS_EGG.get()), - Item.byBlock(ModBlocks.CHILESAURUS_EGG.get()) + Item.byBlock(ModBlocks.CHILESAURUS_EGG.get()), + Item.byBlock(ModBlocks.COELACANTH_EGG.get()), + Item.byBlock(ModBlocks.MAWSONIA_EGG.get()), + Item.byBlock(ModBlocks.ALLIGATOR_GAR_EGG.get()) ); helper.tag(ModTags.Items.FOSSILS, @@ -416,7 +428,10 @@ public class ModItemTagProvider { ModItems.SUCHOMIMUS_SKULL_FOSSIL.get(), ModItems.MUSSASAURUS_SKULL_FOSSIL.get(), ModItems.THESCELOSAURUS_SKULL_FOSSIL.get(), - ModItems.CHILESAURUS_SKULL_FOSSIL.get() + ModItems.CHILESAURUS_SKULL_FOSSIL.get(), + ModItems.COELACANTH_SKULL_FOSSIL.get(), + ModItems.MAWSONIA_SKULL_FOSSIL.get(), + ModItems.ALLIGATOR_GAR_SKULL_FOSSIL.get() ); helper.tag(ModTags.Items.SKULLS, @@ -498,7 +513,10 @@ public class ModItemTagProvider { ModItems.FRESH_SUCHOMIMUS_SKULL.get(), ModItems.FRESH_MUSSASAURUS_SKULL.get(), ModItems.FRESH_THESCELOSAURUS_SKULL.get(), - ModItems.FRESH_CHILESAURUS_SKULL.get() + ModItems.FRESH_CHILESAURUS_SKULL.get(), + ModItems.FRESH_COELACANTH_SKULL.get(), + ModItems.FRESH_MAWSONIA_SKULL.get(), + ModItems.FRESH_ALLIGATOR_GAR_SKULL.get() ); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModRecipeProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModRecipeProvider.java index b2da4a5..d3773e8 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModRecipeProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModRecipeProvider.java @@ -130,6 +130,7 @@ public class ModRecipeProvider { helper.buildShaped(RecipeCategory.MISC, ModBlocks.EMBRYONIC_MACHINE.get(), 1, new String[]{"AAA", "BCB", "ADA"}, 'A', Items.IRON_INGOT, 'B', ModItems.TEST_TUBE.get(), 'C', Items.IRON_NUGGET, 'D', Items.REDSTONE); helper.buildShaped(RecipeCategory.MISC, ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get(), 1, new String[]{"AB ", "CDE", "FAF"}, 'A', Items.IRON_INGOT, 'B', ModItems.SYRINGE.get(), 'C', ModItems.SCREEN.get(), 'D', ModItems.CABLE.get(), 'E', ModItems.PROCESSOR.get(), 'F', Items.FLINT); helper.buildShaped(RecipeCategory.MISC, ModBlocks.INCUBATOR.get(), 1, new String[]{"AAA", "BCB", "DED"}, 'A', Blocks.GLASS, 'B', Items.COPPER_INGOT, 'C', Blocks.HAY_BLOCK, 'D', Items.IRON_INGOT, 'E', ModItems.CABLE.get()); + helper.buildShaped(RecipeCategory.MISC, ModBlocks.CULTIVATOR.get(), 1, new String[]{"AAA", "BCB", "DED"}, 'A', Blocks.GLASS, 'B', Items.COPPER_INGOT, 'C', Blocks.HAY_BLOCK, 'D', Items.IRON_INGOT, 'E', ModItems.CABLE.get()); helper.buildShaped(RecipeCategory.MISC, ModItems.WRENCH.get(), 1, new String[]{" A ", " BA", "B "}, 'A', Items.IRON_INGOT, 'B', Items.IRON_NUGGET); helper.buildShaped(RecipeCategory.MISC, ModBlocks.ITEM_PIPE.get(), 8, new String[]{"AAA"}, 'A', ModItems.CABLE.get()); helper.buildShaped(RecipeCategory.MISC, ModBlocks.FLUID_PIPE.get(), 8, new String[]{" A ", "BBB", " A "}, 'A', Items.WATER_BUCKET, 'B', ModItems.CABLE.get()); @@ -152,7 +153,9 @@ public class ModRecipeProvider { helper.buildShapeless(RecipeCategory.MISC, ModBlocks.WHITE_EMBRYO_CALCIFICATION_MACHINE.get(), 1, "white_embryo_calcification_machine_from_embryo_calcification_machine", ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get()); helper.buildShapeless(RecipeCategory.MISC, ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get(), 1, "embryo_calcification_machine_from_white_embryo_calcification_machine", ModBlocks.WHITE_EMBRYO_CALCIFICATION_MACHINE.get()); helper.buildShapeless(RecipeCategory.MISC, ModBlocks.WHITE_INCUBATOR.get(), 1, "white_incubator_from_incubator", ModBlocks.INCUBATOR.get()); + helper.buildShapeless(RecipeCategory.MISC, ModBlocks.WHITE_CULTIVATOR.get(), 1, "white_cultivator_from_cultivator", ModBlocks.CULTIVATOR.get()); helper.buildShapeless(RecipeCategory.MISC, ModBlocks.INCUBATOR.get(), 1, "incubator_from_white_incubator", ModBlocks.WHITE_INCUBATOR.get()); + helper.buildShapeless(RecipeCategory.MISC, ModBlocks.CULTIVATOR.get(), 1, "cultivator_from_white_cultivator", ModBlocks.WHITE_CULTIVATOR.get()); helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.APATOSAURUS_TISSUE.get(), ModItems.APATOSAURUS_DNA.get(), 1); helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.ALBERTOSAURUS_TISSUE.get(), ModItems.ALBERTOSAURUS_DNA.get(), 1); @@ -232,6 +235,9 @@ public class ModRecipeProvider { helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.CHILESAURUS_TISSUE.get(), ModItems.CHILESAURUS_DNA.get(), 1); helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.THESCELOSAURUS_TISSUE.get(), ModItems.THESCELOSAURUS_DNA.get(), 1); helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.MUSSASAURUS_TISSUE.get(), ModItems.MUSSASAURUS_DNA.get(), 1); + helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.COELACANTH_TISSUE.get(), ModItems.COELACANTH_DNA.get(), 1); + helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.MAWSONIA_TISSUE.get(), ModItems.MAWSONIA_DNA.get(), 1); + helper.dnaExtracting(ModItems.TEST_TUBE.get(), ModItems.ALLIGATOR_GAR_TISSUE.get(), ModItems.ALLIGATOR_GAR_DNA.get(), 1); helper.fossilCleaning(ModBlocks.STONE_FOSSIL.get(), ModItems.APATOSAURUS_SKULL_FOSSIL.get(), 1); helper.fossilCleaning(ModBlocks.DEEPSLATE_FOSSIL.get(), ModItems.VELOCIRAPTOR_SKULL_FOSSIL.get(), 1); @@ -311,6 +317,9 @@ public class ModRecipeProvider { helper.fossilGrinding(ModItems.CHILESAURUS_SKULL_FOSSIL.get(), ModItems.CHILESAURUS_TISSUE.get(), 1); helper.fossilGrinding(ModItems.THESCELOSAURUS_SKULL_FOSSIL.get(), ModItems.THESCELOSAURUS_TISSUE.get(), 1); helper.fossilGrinding(ModItems.MUSSASAURUS_SKULL_FOSSIL.get(), ModItems.MUSSASAURUS_TISSUE.get(), 1); + helper.fossilGrinding(ModItems.COELACANTH_SKULL_FOSSIL.get(), ModItems.COELACANTH_TISSUE.get(), 1); + helper.fossilGrinding(ModItems.MAWSONIA_SKULL_FOSSIL.get(), ModItems.MAWSONIA_TISSUE.get(), 1); + helper.fossilGrinding(ModItems.ALLIGATOR_GAR_SKULL_FOSSIL.get(), ModItems.ALLIGATOR_GAR_TISSUE.get(), 1); helper.skullToTissue(ModItems.FRESH_ALBERTOSAURUS_SKULL.get(), ModItems.ALBERTOSAURUS_TISSUE.get(), 1); helper.skullToTissue(ModItems.FRESH_APATOSAURUS_SKULL.get(), ModItems.APATOSAURUS_TISSUE.get(), 1); @@ -390,6 +399,9 @@ public class ModRecipeProvider { helper.skullToTissue(ModItems.FRESH_CHILESAURUS_SKULL.get(), ModItems.CHILESAURUS_TISSUE.get(), 1); helper.skullToTissue(ModItems.FRESH_THESCELOSAURUS_SKULL.get(), ModItems.THESCELOSAURUS_TISSUE.get(), 1); helper.skullToTissue(ModItems.FRESH_MUSSASAURUS_SKULL.get(), ModItems.MUSSASAURUS_TISSUE.get(), 1); + helper.skullToTissue(ModItems.FRESH_COELACANTH_SKULL.get(), ModItems.COELACANTH_TISSUE.get(), 1); + helper.skullToTissue(ModItems.FRESH_MAWSONIA_SKULL.get(), ModItems.MAWSONIA_TISSUE.get(), 1); + helper.skullToTissue(ModItems.FRESH_ALLIGATOR_GAR_SKULL.get(), ModItems.ALLIGATOR_GAR_TISSUE.get(), 1); helper.dnaAnalyzing(ModItems.TEST_TUBE.get(), ModItems.FROG_MATERIAL.get(), ModItems.FROG_DNA.get(), 1); @@ -487,6 +499,9 @@ public class ModRecipeProvider { helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.CHILESAURUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.CHILESAURUS_SYRINGE.get(), 1); helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.THESCELOSAURUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.THESCELOSAURUS_SYRINGE.get(), 1); helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.MUSSASAURUS_DNA.get(), ModItems.FROG_DNA.get(), ModItems.MUSSASAURUS_SYRINGE.get(), 1); + helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.COELACANTH_DNA.get(), ModItems.FROG_DNA.get(), ModItems.COELACANTH_SYRINGE.get(), 1); + helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.MAWSONIA_DNA.get(), ModItems.FROG_DNA.get(), ModItems.MAWSONIA_SYRINGE.get(), 1); + helper.embryonicMachine(ModItems.SYRINGE.get(), ModItems.ALLIGATOR_GAR_DNA.get(), ModItems.FROG_DNA.get(), ModItems.ALLIGATOR_GAR_SYRINGE.get(), 1); helper.embryoCalcification(ModItems.ALBERTOSAURUS_SYRINGE.get(), Items.EGG, ModBlocks.ALBERTOSAURUS_EGG.get(), 1); helper.embryoCalcification(ModItems.APATOSAURUS_SYRINGE.get(), Items.EGG, ModBlocks.APATOSAURUS_EGG.get(), 1); @@ -566,6 +581,9 @@ public class ModRecipeProvider { helper.embryoCalcification(ModItems.CHILESAURUS_SYRINGE.get(), Items.EGG, ModBlocks.CHILESAURUS_EGG.get(), 1); helper.embryoCalcification(ModItems.THESCELOSAURUS_SYRINGE.get(), Items.EGG, ModBlocks.THESCELOSAURUS_EGG.get(), 1); helper.embryoCalcification(ModItems.MUSSASAURUS_SYRINGE.get(), Items.EGG, ModBlocks.MUSSASAURUS_EGG.get(), 1); + helper.embryoCalcification(ModItems.COELACANTH_SYRINGE.get(), Items.EGG, ModBlocks.COELACANTH_EGG.get(), 1); + helper.embryoCalcification(ModItems.MAWSONIA_SYRINGE.get(), Items.EGG, ModBlocks.MAWSONIA_EGG.get(), 1); + helper.embryoCalcification(ModItems.ALLIGATOR_GAR_SYRINGE.get(), Items.EGG, ModBlocks.ALLIGATOR_GAR_EGG.get(), 1); helper.incubating(ModBlocks.APATOSAURUS_EGG.get(), ModBlocks.INCUBATED_APATOSAURUS_EGG.get(), 1); helper.incubating(ModBlocks.ALBERTOSAURUS_EGG.get(), ModBlocks.INCUBATED_ALBERTOSAURUS_EGG.get(), 1); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/custom/CultivatingRecipeBuilder.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/custom/CultivatingRecipeBuilder.java new file mode 100644 index 0000000..172ea71 --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/custom/CultivatingRecipeBuilder.java @@ -0,0 +1,192 @@ +package net.cmr.jurassicrevived.datagen.custom; + +import net.cmr.jurassicrevived.recipe.CultivatorRecipe; +import net.minecraft.advancements.*; +import net.minecraft.advancements.critereon.InventoryChangeTrigger; +import net.minecraft.advancements.critereon.RecipeUnlockedTrigger; +import net.minecraft.core.NonNullList; +import net.minecraft.core.registries.BuiltInRegistries; +//? if >1.20.1 { +/*import net.minecraft.data.recipes.RecipeOutput; +*///?} +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.ItemLike; + +import java.util.LinkedHashMap; +import java.util.Map; + +//? if <=1.20.1 { +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import net.cmr.jurassicrevived.recipe.ModRecipes; +import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; +//?} + +public class CultivatingRecipeBuilder { + private java.util.Optional firstItem = java.util.Optional.empty(); + private java.util.Optional resultItem = java.util.Optional.empty(); + private final int count; + //? if >1.20.1 { + /*private final Map> criteria; + *///?} else { + private final Map criteria; + //?} + private final Map weights = new java.util.HashMap<>(); + + public CultivatingRecipeBuilder(ItemLike ingredient, ItemLike placeholderResult, int count) { + this.firstItem = java.util.Optional.of(ingredient); + this.resultItem = java.util.Optional.of(placeholderResult.asItem()); + this.count = count; + this.criteria = new LinkedHashMap(); + } + + public static CultivatingRecipeBuilder randomFossil(ItemLike consumableInput, ItemLike placeholderResult, int count) { + return new CultivatingRecipeBuilder(consumableInput, placeholderResult, count); + } + + public CultivatingRecipeBuilder addFossilWeight(ItemLike fossilItem, int weight) { + ResourceLocation id = BuiltInRegistries.ITEM.getKey(fossilItem.asItem()); + if (id != null) { + weights.put(id, weight); + } + return this; + } + + //? if >1.20.1 { + /*public void save(RecipeOutput output) { + ResourceLocation resultKey = BuiltInRegistries.ITEM.getKey(this.resultItem.orElseThrow()); + ResourceLocation id = ResourceLocation.fromNamespaceAndPath( + resultKey.getNamespace(), + resultKey.getPath() + "_from_cultivating" + ); + save(output, id); + } + + public void save(RecipeOutput output, ResourceLocation recipeId) { + NonNullList inputs = NonNullList.create(); + inputs.add(Ingredient.of(firstItem.orElseThrow())); + ItemStack result = new ItemStack(resultItem.orElseThrow(), this.count); + + CultivatorRecipe recipe = new CultivatorRecipe(inputs, result, Map.copyOf(this.weights)); + + AdvancementHolder advancementHolder = null; + if (!this.criteria.isEmpty()) { + Advancement.Builder builder = output.advancement(); + for (Map.Entry> e : this.criteria.entrySet()) { + builder.addCriterion(e.getKey(), e.getValue()); + } + builder.rewards(AdvancementRewards.Builder.recipe(recipeId)); + builder.requirements(AdvancementRequirements.Strategy.OR); + advancementHolder = builder.build(recipeId.withPrefix("recipes/")); + } + + output.accept(recipeId, recipe, advancementHolder); + } + *///?} else { + public void save(Consumer consumer) { + ResourceLocation resultKey = BuiltInRegistries.ITEM.getKey(this.resultItem.orElseThrow()); + ResourceLocation id = new ResourceLocation( + resultKey.getNamespace(), + resultKey.getPath() + "_from_cultivating" + ); + save(consumer, id); + } + + public void save(Consumer consumer, ResourceLocation recipeId) { + Advancement.Builder advancementBuilder = Advancement.Builder.advancement(); + advancementBuilder.parent(new ResourceLocation("recipes/root")) + .addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(recipeId)) + .rewards(AdvancementRewards.Builder.recipe(recipeId)) + .requirements(RequirementsStrategy.OR); + this.criteria.forEach(advancementBuilder::addCriterion); + + consumer.accept(new Result( + recipeId, + Ingredient.of(firstItem.orElseThrow()), + this.resultItem.orElseThrow(), + this.count, + this.weights, + advancementBuilder, + new ResourceLocation(recipeId.getNamespace(), "recipes/" + recipeId.getPath()) + )); + } + + public static class Result implements FinishedRecipe { + private final ResourceLocation id; + private final Ingredient first; + private final Item result; + private final int count; + private final Map weights; + private final Advancement.Builder advancement; + private final ResourceLocation advancementId; + + public Result(ResourceLocation id, Ingredient first, Item result, int count, Map weights, Advancement.Builder advancement, ResourceLocation advancementId) { + this.id = id; + this.first = first; + this.result = result; + this.count = count; + this.weights = weights; + this.advancement = advancement; + this.advancementId = advancementId; + } + + @Override + public void serializeRecipeData(JsonObject json) { + JsonArray ingredients = new JsonArray(); + ingredients.add(first.toJson()); + json.add("ingredients", ingredients); + + JsonObject resultObj = new JsonObject(); + resultObj.addProperty("item", BuiltInRegistries.ITEM.getKey(result).toString()); + if (count > 1) { + resultObj.addProperty("count", count); + } + json.add("result", resultObj); + + if (!weights.isEmpty()) { + JsonObject weightsObj = new JsonObject(); + weights.forEach((k, v) -> weightsObj.addProperty(k.toString(), v)); + json.add("weights", weightsObj); + } + } + + @Override + public ResourceLocation getId() { + return id; + } + + @Override + public RecipeSerializer getType() { + return ModRecipes.CULTIVATOR_SERIALIZER.get(); + } + + @Nullable + @Override + public JsonObject serializeAdvancement() { + return advancement.serializeToJson(); + } + + @Nullable + @Override + public ResourceLocation getAdvancementId() { + return advancementId; + } + } + //?} + + //? if >1.20.1 { + /*public CultivatingRecipeBuilder unlockedBy(String name, Criterion criterion) { + *///?} else { + public CultivatingRecipeBuilder unlockedBy(String name, InventoryChangeTrigger.TriggerInstance criterion) { + //?} + this.criteria.put(name, criterion); + return this; + } +} diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/ModEntities.java b/common/src/main/java/net/cmr/jurassicrevived/entity/ModEntities.java index 271c77c..92a3b65 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/ModEntities.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/ModEntities.java @@ -534,6 +534,9 @@ public class ModEntities { registerGroundAnimalSpawn(CHILESAURUS); registerGroundAnimalSpawn(MUSSASAURUS); registerGroundAnimalSpawn(THESCELOSAURUS); + registerGroundAnimalSpawn(COELACANTH); + registerGroundAnimalSpawn(MAWSONIA); + registerGroundAnimalSpawn(ALLIGATOR_GAR); } private static void registerGroundAnimalSpawn(RegistrySupplier> entityType) { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusModel.java index 15f307a..0d6f16d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusModel.java @@ -25,6 +25,9 @@ public class CompsognathusModel extends GeoModel { map.put(CompsognathusVariant.FEMALE, Constants.rl("textures/entity/compsognathus_female.png")); }); + private static final ResourceLocation REBIRTH_LOCATION = + Constants.rl("textures/entity/compsognathus_rebirth.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -36,6 +39,10 @@ public class CompsognathusModel extends GeoModel { @Override public ResourceLocation getTextureResource(CompsognathusEntity animatable) { + if (animatable.hasCustomName() && "rebirth".equalsIgnoreCase(animatable.getName().getString())) { + return REBIRTH_LOCATION; + } + return LOCATION_BY_VARIANT.get(animatable.getVariant()); } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlligatorGarEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlligatorGarEntity.java index 6b8fc50..676129d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlligatorGarEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlligatorGarEntity.java @@ -6,6 +6,7 @@ import net.cmr.jurassicrevived.entity.ai.DinoData; import net.cmr.jurassicrevived.entity.ai.DinoEntityBase; import net.cmr.jurassicrevived.entity.ai.IDinoData; import net.cmr.jurassicrevived.entity.client.AlligatorGarVariant; +import net.cmr.jurassicrevived.item.ModItems; import net.minecraft.Util; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -22,6 +23,7 @@ import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation; import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.block.Block; @@ -95,10 +97,10 @@ public class AlligatorGarEntity extends DinoEntityBase implements GeoEntity { return new WaterBoundPathNavigation(this, pLevel); } - //@Override - //public ItemStack getPickResult() { - // return new ItemStack(ModItems.ALLIGATOR_GAR_SPAWN_EGG.get()); - //} + @Override + public ItemStack getPickResult() { + return new ItemStack(ModItems.ALLIGATOR_GAR_SPAWN_EGG.get()); + } @Override public boolean isCarnivore() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelacanthEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelacanthEntity.java index 4273d53..6a66a8b 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelacanthEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelacanthEntity.java @@ -101,10 +101,10 @@ public class CoelacanthEntity extends DinoEntityBase implements GeoEntity { return new WaterBoundPathNavigation(this, pLevel); } - //@Override - //public ItemStack getPickResult() { - // return new ItemStack(ModItems.COELACANTH_SPAWN_EGG.get()); - //} + @Override + public ItemStack getPickResult() { + return new ItemStack(ModItems.COELACANTH_SPAWN_EGG.get()); + } @Override public boolean isCarnivore() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MawsoniaEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MawsoniaEntity.java index 9f32b32..1d9d876 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MawsoniaEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MawsoniaEntity.java @@ -6,6 +6,7 @@ import net.cmr.jurassicrevived.entity.ai.DinoData; import net.cmr.jurassicrevived.entity.ai.DinoEntityBase; import net.cmr.jurassicrevived.entity.ai.IDinoData; import net.cmr.jurassicrevived.entity.client.MawsoniaVariant; +import net.cmr.jurassicrevived.item.ModItems; import net.minecraft.Util; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -22,6 +23,7 @@ import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation; import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.block.Block; @@ -95,10 +97,10 @@ public class MawsoniaEntity extends DinoEntityBase implements GeoEntity { return new WaterBoundPathNavigation(this, pLevel); } - //@Override - //public ItemStack getPickResult() { - // return new ItemStack(ModItems.MAWSONIA_SPAWN_EGG.get()); - //} + @Override + public ItemStack getPickResult() { + return new ItemStack(ModItems.MAWSONIA_SPAWN_EGG.get()); + } @Override public boolean isCarnivore() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java b/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java index 0a93766..be767a3 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java +++ b/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java @@ -124,6 +124,7 @@ public class ModCreativeTabs { output.accept(ModBlocks.EMBRYONIC_MACHINE.get()); output.accept(ModBlocks.EMBRYO_CALCIFICATION_MACHINE.get()); output.accept(ModBlocks.INCUBATOR.get()); + output.accept(ModBlocks.CULTIVATOR.get()); output.accept(ModBlocks.WHITE_GENERATOR.get()); output.accept(ModBlocks.WHITE_DNA_EXTRACTOR.get()); @@ -134,6 +135,7 @@ public class ModCreativeTabs { output.accept(ModBlocks.WHITE_EMBRYONIC_MACHINE.get()); output.accept(ModBlocks.WHITE_EMBRYO_CALCIFICATION_MACHINE.get()); output.accept(ModBlocks.WHITE_INCUBATOR.get()); + output.accept(ModBlocks.WHITE_CULTIVATOR.get()); output.accept(ModBlocks.STONE_FOSSIL.get()); output.accept(ModBlocks.DEEPSLATE_FOSSIL.get()); @@ -163,6 +165,7 @@ public class ModCreativeTabs { // Skull fossils (alphabetical) output.accept(ModItems.ACHILLOBATOR_SKULL_FOSSIL.get()); output.accept(ModItems.ALBERTOSAURUS_SKULL_FOSSIL.get()); + output.accept(ModItems.ALLIGATOR_GAR_SKULL_FOSSIL.get()); output.accept(ModItems.ALLOSAURUS_SKULL_FOSSIL.get()); output.accept(ModItems.ALVAREZSAURUS_SKULL_FOSSIL.get()); output.accept(ModItems.ANKYLOSAURUS_SKULL_FOSSIL.get()); @@ -176,6 +179,7 @@ public class ModCreativeTabs { output.accept(ModItems.CERATOSAURUS_SKULL_FOSSIL.get()); output.accept(ModItems.CHASMOSAURUS_SKULL_FOSSIL.get()); output.accept(ModItems.CHILESAURUS_SKULL_FOSSIL.get()); + output.accept(ModItems.COELACANTH_SKULL_FOSSIL.get()); output.accept(ModItems.COELOPHYSIS_SKULL_FOSSIL.get()); output.accept(ModItems.COELURUS_SKULL_FOSSIL.get()); output.accept(ModItems.COMPSOGNATHUS_SKULL_FOSSIL.get()); @@ -200,6 +204,7 @@ public class ModCreativeTabs { output.accept(ModItems.LUDODACTYLUS_SKULL_FOSSIL.get()); output.accept(ModItems.MAJUNGASAURUS_SKULL_FOSSIL.get()); output.accept(ModItems.MAMENCHISAURUS_SKULL_FOSSIL.get()); + output.accept(ModItems.MAWSONIA_SKULL_FOSSIL.get()); output.accept(ModItems.METRIACANTHOSAURUS_SKULL_FOSSIL.get()); output.accept(ModItems.MOGANOPTERUS_SKULL_FOSSIL.get()); output.accept(ModItems.MUSSASAURUS_SKULL_FOSSIL.get()); @@ -240,6 +245,7 @@ public class ModCreativeTabs { // Fresh skulls (alphabetical) output.accept(ModItems.FRESH_ACHILLOBATOR_SKULL.get()); output.accept(ModItems.FRESH_ALBERTOSAURUS_SKULL.get()); + output.accept(ModItems.FRESH_ALLIGATOR_GAR_SKULL.get()); output.accept(ModItems.FRESH_ALLOSAURUS_SKULL.get()); output.accept(ModItems.FRESH_ALVAREZSAURUS_SKULL.get()); output.accept(ModItems.FRESH_ANKYLOSAURUS_SKULL.get()); @@ -253,6 +259,7 @@ public class ModCreativeTabs { output.accept(ModItems.FRESH_CERATOSAURUS_SKULL.get()); output.accept(ModItems.FRESH_CHASMOSAURUS_SKULL.get()); output.accept(ModItems.FRESH_CHILESAURUS_SKULL.get()); + output.accept(ModItems.FRESH_COELACANTH_SKULL.get()); output.accept(ModItems.FRESH_COELOPHYSIS_SKULL.get()); output.accept(ModItems.FRESH_COELURUS_SKULL.get()); output.accept(ModItems.FRESH_COMPSOGNATHUS_SKULL.get()); @@ -280,6 +287,7 @@ public class ModCreativeTabs { output.accept(ModItems.FRESH_LUDODACTYLUS_SKULL.get()); output.accept(ModItems.FRESH_MAJUNGASAURUS_SKULL.get()); output.accept(ModItems.FRESH_MAMENCHISAURUS_SKULL.get()); + output.accept(ModItems.FRESH_MAWSONIA_SKULL.get()); output.accept(ModItems.FRESH_METRIACANTHOSAURUS_SKULL.get()); output.accept(ModItems.FRESH_MOGANOPTERUS_SKULL.get()); output.accept(ModItems.FRESH_MUSSASAURUS_SKULL.get()); @@ -319,6 +327,7 @@ public class ModCreativeTabs { // Tissue (alphabetical) output.accept(ModItems.ACHILLOBATOR_TISSUE.get()); output.accept(ModItems.ALBERTOSAURUS_TISSUE.get()); + output.accept(ModItems.ALLIGATOR_GAR_TISSUE.get()); output.accept(ModItems.ALLOSAURUS_TISSUE.get()); output.accept(ModItems.ALVAREZSAURUS_TISSUE.get()); output.accept(ModItems.ANKYLOSAURUS_TISSUE.get()); @@ -332,6 +341,7 @@ public class ModCreativeTabs { output.accept(ModItems.CERATOSAURUS_TISSUE.get()); output.accept(ModItems.CHASMOSAURUS_TISSUE.get()); output.accept(ModItems.CHILESAURUS_TISSUE.get()); + output.accept(ModItems.COELACANTH_TISSUE.get()); output.accept(ModItems.COELOPHYSIS_TISSUE.get()); output.accept(ModItems.COELURUS_TISSUE.get()); output.accept(ModItems.COMPSOGNATHUS_TISSUE.get()); @@ -359,6 +369,7 @@ public class ModCreativeTabs { output.accept(ModItems.LUDODACTYLUS_TISSUE.get()); output.accept(ModItems.MAJUNGASAURUS_TISSUE.get()); output.accept(ModItems.MAMENCHISAURUS_TISSUE.get()); + output.accept(ModItems.MAWSONIA_TISSUE.get()); output.accept(ModItems.METRIACANTHOSAURUS_TISSUE.get()); output.accept(ModItems.MOGANOPTERUS_TISSUE.get()); output.accept(ModItems.MUSSASAURUS_TISSUE.get()); @@ -399,6 +410,7 @@ public class ModCreativeTabs { // DNA (alphabetical) output.accept(ModItems.ACHILLOBATOR_DNA.get()); output.accept(ModItems.ALBERTOSAURUS_DNA.get()); + output.accept(ModItems.ALLIGATOR_GAR_DNA.get()); output.accept(ModItems.ALLOSAURUS_DNA.get()); output.accept(ModItems.ALVAREZSAURUS_DNA.get()); output.accept(ModItems.ANKYLOSAURUS_DNA.get()); @@ -412,6 +424,7 @@ public class ModCreativeTabs { output.accept(ModItems.CERATOSAURUS_DNA.get()); output.accept(ModItems.CHASMOSAURUS_DNA.get()); output.accept(ModItems.CHILESAURUS_DNA.get()); + output.accept(ModItems.COELACANTH_DNA.get()); output.accept(ModItems.COELOPHYSIS_DNA.get()); output.accept(ModItems.COELURUS_DNA.get()); output.accept(ModItems.COMPSOGNATHUS_DNA.get()); @@ -439,6 +452,7 @@ public class ModCreativeTabs { output.accept(ModItems.LUDODACTYLUS_DNA.get()); output.accept(ModItems.MAJUNGASAURUS_DNA.get()); output.accept(ModItems.MAMENCHISAURUS_DNA.get()); + output.accept(ModItems.MAWSONIA_DNA.get()); output.accept(ModItems.METRIACANTHOSAURUS_DNA.get()); output.accept(ModItems.MOGANOPTERUS_DNA.get()); output.accept(ModItems.MUSSASAURUS_DNA.get()); @@ -479,6 +493,7 @@ public class ModCreativeTabs { // Syringes (alphabetical) output.accept(ModItems.ACHILLOBATOR_SYRINGE.get()); output.accept(ModItems.ALBERTOSAURUS_SYRINGE.get()); + output.accept(ModItems.ALLIGATOR_GAR_SYRINGE.get()); output.accept(ModItems.ALLOSAURUS_SYRINGE.get()); output.accept(ModItems.ALVAREZSAURUS_SYRINGE.get()); output.accept(ModItems.ANKYLOSAURUS_SYRINGE.get()); @@ -492,6 +507,7 @@ public class ModCreativeTabs { output.accept(ModItems.CERATOSAURUS_SYRINGE.get()); output.accept(ModItems.CHASMOSAURUS_SYRINGE.get()); output.accept(ModItems.CHILESAURUS_SYRINGE.get()); + output.accept(ModItems.COELACANTH_SYRINGE.get()); output.accept(ModItems.COELOPHYSIS_SYRINGE.get()); output.accept(ModItems.COELURUS_SYRINGE.get()); output.accept(ModItems.COMPSOGNATHUS_SYRINGE.get()); @@ -519,6 +535,7 @@ public class ModCreativeTabs { output.accept(ModItems.LUDODACTYLUS_SYRINGE.get()); output.accept(ModItems.MAJUNGASAURUS_SYRINGE.get()); output.accept(ModItems.MAMENCHISAURUS_SYRINGE.get()); + output.accept(ModItems.MAWSONIA_SYRINGE.get()); output.accept(ModItems.METRIACANTHOSAURUS_SYRINGE.get()); output.accept(ModItems.MOGANOPTERUS_SYRINGE.get()); output.accept(ModItems.MUSSASAURUS_SYRINGE.get()); @@ -559,6 +576,7 @@ public class ModCreativeTabs { // Eggs (alphabetical) output.accept(ModBlocks.ACHILLOBATOR_EGG.get()); output.accept(ModBlocks.ALBERTOSAURUS_EGG.get()); + output.accept(ModBlocks.ALLIGATOR_GAR_EGG.get()); output.accept(ModBlocks.ALLOSAURUS_EGG.get()); output.accept(ModBlocks.ALVAREZSAURUS_EGG.get()); output.accept(ModBlocks.ANKYLOSAURUS_EGG.get()); @@ -572,6 +590,7 @@ public class ModCreativeTabs { output.accept(ModBlocks.CERATOSAURUS_EGG.get()); output.accept(ModBlocks.CHASMOSAURUS_EGG.get()); output.accept(ModBlocks.CHILESAURUS_EGG.get()); + output.accept(ModBlocks.COELACANTH_EGG.get()); output.accept(ModBlocks.COELOPHYSIS_EGG.get()); output.accept(ModBlocks.COELURUS_EGG.get()); output.accept(ModBlocks.COMPSOGNATHUS_EGG.get()); @@ -599,6 +618,7 @@ public class ModCreativeTabs { output.accept(ModBlocks.LUDODACTYLUS_EGG.get()); output.accept(ModBlocks.MAJUNGASAURUS_EGG.get()); output.accept(ModBlocks.MAMENCHISAURUS_EGG.get()); + output.accept(ModBlocks.MAWSONIA_EGG.get()); output.accept(ModBlocks.METRIACANTHOSAURUS_EGG.get()); output.accept(ModBlocks.MOGANOPTERUS_EGG.get()); output.accept(ModBlocks.MUSSASAURUS_EGG.get()); @@ -644,6 +664,7 @@ public class ModCreativeTabs { builder.displayItems((params, output) -> { output.accept(ModItems.ACHILLOBATOR_SPAWN_EGG.get()); output.accept(ModItems.ALBERTOSAURUS_SPAWN_EGG.get()); + output.accept(ModItems.ALLIGATOR_GAR_SPAWN_EGG.get()); output.accept(ModItems.ALLOSAURUS_SPAWN_EGG.get()); output.accept(ModItems.ALVAREZSAURUS_SPAWN_EGG.get()); output.accept(ModItems.ANKYLOSAURUS_SPAWN_EGG.get()); @@ -657,6 +678,7 @@ public class ModCreativeTabs { output.accept(ModItems.CERATOSAURUS_SPAWN_EGG.get()); output.accept(ModItems.CHASMOSAURUS_SPAWN_EGG.get()); output.accept(ModItems.CHILESAURUS_SPAWN_EGG.get()); + output.accept(ModItems.COELACANTH_SPAWN_EGG.get()); output.accept(ModItems.COELOPHYSIS_SPAWN_EGG.get()); output.accept(ModItems.COELURUS_SPAWN_EGG.get()); output.accept(ModItems.COMPSOGNATHUS_SPAWN_EGG.get()); @@ -684,6 +706,7 @@ public class ModCreativeTabs { output.accept(ModItems.LUDODACTYLUS_SPAWN_EGG.get()); output.accept(ModItems.MAJUNGASAURUS_SPAWN_EGG.get()); output.accept(ModItems.MAMENCHISAURUS_SPAWN_EGG.get()); + output.accept(ModItems.MAWSONIA_SPAWN_EGG.get()); output.accept(ModItems.METRIACANTHOSAURUS_SPAWN_EGG.get()); output.accept(ModItems.MOGANOPTERUS_SPAWN_EGG.get()); output.accept(ModItems.MUSSASAURUS_SPAWN_EGG.get()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java b/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java index 80372af..8443334 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java +++ b/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java @@ -189,6 +189,12 @@ public class ModItems { () -> new CustomGenderedSpawnEggItem(ModEntities.THESCELOSAURUS, 0xff6d7a83, 0xffbac6d1, new Item.Properties())); public static final RegistrySupplier MUSSASAURUS_SPAWN_EGG = ITEMS.register("mussasaurus_spawn_egg", () -> new CustomGenderedSpawnEggItem(ModEntities.MUSSASAURUS, 0xff6c6724, 0xff222611, new Item.Properties())); + public static final RegistrySupplier COELACANTH_SPAWN_EGG = ITEMS.register("coelacanth_spawn_egg", + () -> new CustomGenderedSpawnEggItem(ModEntities.COELACANTH, 0xff3a4862, 0xff616e87, new Item.Properties())); + public static final RegistrySupplier MAWSONIA_SPAWN_EGG = ITEMS.register("mawsonia_spawn_egg", + () -> new CustomGenderedSpawnEggItem(ModEntities.MAWSONIA, 0xff595d4d, 0xffd8d8b6, new Item.Properties())); + public static final RegistrySupplier ALLIGATOR_GAR_SPAWN_EGG = ITEMS.register("alligator_gar_spawn_egg", + () -> new CustomGenderedSpawnEggItem(ModEntities.ALLIGATOR_GAR, 0xff969180, 0xffe4675a, new Item.Properties())); public static final RegistrySupplier TEST_TUBE = ITEMS.register("test_tube", () -> new Item(new Item.Properties().stacksTo(16))); @@ -278,6 +284,9 @@ public class ModItems { public static final RegistrySupplier CHILESAURUS_SKULL_FOSSIL = ITEMS.register("chilesaurus_skull_fossil", () -> new Item(new Item.Properties().stacksTo(16))); public static final RegistrySupplier THESCELOSAURUS_SKULL_FOSSIL = ITEMS.register("thescelosaurus_skull_fossil", () -> new Item(new Item.Properties().stacksTo(16))); public static final RegistrySupplier MUSSASAURUS_SKULL_FOSSIL = ITEMS.register("mussasaurus_skull_fossil", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistrySupplier COELACANTH_SKULL_FOSSIL = ITEMS.register("coelacanth_skull_fossil", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistrySupplier MAWSONIA_SKULL_FOSSIL = ITEMS.register("mawsonia_skull_fossil", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistrySupplier ALLIGATOR_GAR_SKULL_FOSSIL = ITEMS.register("alligator_gar_skull_fossil", () -> new Item(new Item.Properties().stacksTo(16))); public static final RegistrySupplier FRESH_VELOCIRAPTOR_SKULL = ITEMS.register("fresh_velociraptor_skull", () -> new Item(new Item.Properties().stacksTo(16))); @@ -358,6 +367,9 @@ public class ModItems { public static final RegistrySupplier FRESH_CHILESAURUS_SKULL = ITEMS.register("fresh_chilesaurus_skull", () -> new Item(new Item.Properties().stacksTo(16))); public static final RegistrySupplier FRESH_THESCELOSAURUS_SKULL = ITEMS.register("fresh_thescelosaurus_skull", () -> new Item(new Item.Properties().stacksTo(16))); public static final RegistrySupplier FRESH_MUSSASAURUS_SKULL = ITEMS.register("fresh_mussasaurus_skull", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistrySupplier FRESH_COELACANTH_SKULL = ITEMS.register("fresh_coelacanth_skull", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistrySupplier FRESH_MAWSONIA_SKULL = ITEMS.register("fresh_mawsonia_skull", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistrySupplier FRESH_ALLIGATOR_GAR_SKULL = ITEMS.register("fresh_alligator_gar_skull", () -> new Item(new Item.Properties().stacksTo(16))); // Tissue group @@ -439,6 +451,9 @@ public class ModItems { public static final RegistrySupplier CHILESAURUS_TISSUE = ITEMS.register("chilesaurus_tissue", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.EPIC))); public static final RegistrySupplier THESCELOSAURUS_TISSUE = ITEMS.register("thescelosaurus_tissue", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.EPIC))); public static final RegistrySupplier MUSSASAURUS_TISSUE = ITEMS.register("mussasaurus_tissue", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.EPIC))); + public static final RegistrySupplier COELACANTH_TISSUE = ITEMS.register("coelacanth_tissue", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.EPIC))); + public static final RegistrySupplier MAWSONIA_TISSUE = ITEMS.register("mawsonia_tissue", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.EPIC))); + public static final RegistrySupplier ALLIGATOR_GAR_TISSUE = ITEMS.register("alligator_gar_tissue", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.EPIC))); // DNA group @@ -520,6 +535,9 @@ public class ModItems { public static final RegistrySupplier CHILESAURUS_DNA = ITEMS.register("chilesaurus_dna", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.RARE))); public static final RegistrySupplier THESCELOSAURUS_DNA = ITEMS.register("thescelosaurus_dna", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.RARE))); public static final RegistrySupplier MUSSASAURUS_DNA = ITEMS.register("mussasaurus_dna", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.RARE))); + public static final RegistrySupplier COELACANTH_DNA = ITEMS.register("coelacanth_dna", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.RARE))); + public static final RegistrySupplier MAWSONIA_DNA = ITEMS.register("mawsonia_dna", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.RARE))); + public static final RegistrySupplier ALLIGATOR_GAR_DNA = ITEMS.register("alligator_gar_dna", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.RARE))); // Syringe group @@ -601,7 +619,9 @@ public class ModItems { public static final RegistrySupplier CHILESAURUS_SYRINGE = ITEMS.register("chilesaurus_syringe", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.UNCOMMON))); public static final RegistrySupplier THESCELOSAURUS_SYRINGE = ITEMS.register("thescelosaurus_syringe", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.UNCOMMON))); public static final RegistrySupplier MUSSASAURUS_SYRINGE = ITEMS.register("mussasaurus_syringe", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.UNCOMMON))); - + public static final RegistrySupplier COELACANTH_SYRINGE = ITEMS.register("coelacanth_syringe", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.UNCOMMON))); + public static final RegistrySupplier MAWSONIA_SYRINGE = ITEMS.register("mawsonia_syringe", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.UNCOMMON))); + public static final RegistrySupplier ALLIGATOR_GAR_SYRINGE = ITEMS.register("alligator_gar_syringe", () -> new Item(new Item.Properties().stacksTo(8).rarity(Rarity.UNCOMMON))); public static void register() { ITEMS.register(); diff --git a/common/src/main/java/net/cmr/jurassicrevived/mixin/MenuScreensMixin.java b/common/src/main/java/net/cmr/jurassicrevived/mixin/MenuScreensMixin.java index 733d30f..ab85bb0 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/mixin/MenuScreensMixin.java +++ b/common/src/main/java/net/cmr/jurassicrevived/mixin/MenuScreensMixin.java @@ -25,6 +25,7 @@ public class MenuScreensMixin { MenuRegistry.registerScreenFactory(ModMenuTypes.EMBRYONIC_MACHINE_MENU.get(), EmbryonicMachineScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.EMBRYO_CALCIFICATION_MACHINE_MENU.get(), EmbryoCalcificationMachineScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.INCUBATOR_MENU.get(), IncubatorScreen::new); + MenuRegistry.registerScreenFactory(ModMenuTypes.CULTIVATOR_MENU.get(), CultivatorScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.TANK_MENU.get(), TankScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.POWER_CELL_MENU.get(), PowerCellScreen::new); MenuRegistry.registerScreenFactory(ModMenuTypes.WOOD_CRATE_MENU.get(), CrateScreen::new); diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipe.java new file mode 100644 index 0000000..c2ba1df --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipe.java @@ -0,0 +1,244 @@ +package net.cmr.jurassicrevived.recipe; + +//? if >1.20.1 { +/*import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.HolderLookup; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +*///?} else { +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.core.RegistryAccess; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.util.GsonHelper; +//?} + +import net.cmr.jurassicrevived.util.ModTags; +import net.minecraft.core.NonNullList; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.*; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +//? if >1.20.1 { +/*public record CultivatorRecipe(NonNullList inputs, ItemStack output, Map weights) implements Recipe { + *///?} else { +public class CultivatorRecipe implements Recipe { + private final NonNullList inputs; + private final ItemStack output; + private final ResourceLocation id; + private final Map weights; +//?} + + //? if <=1.20.1 { + public CultivatorRecipe(ResourceLocation id, NonNullList inputs, ItemStack output, Map weights) { + this.id = id; + this.inputs = inputs; + this.output = output; + this.weights = Map.copyOf(weights); + } + //?} + + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + + + + @Override + public boolean matches(@NotNull CultivatorRecipeInput input, Level level) { + if (level.isClientSide()) return false; + if (inputs.isEmpty()) return false; + + // Single fossil block ingredient lives in machine slot 0 (input.getItem(0)) + return inputs.get(0).test(input.getItem(0)); + } + + //? if >1.20.1 { + /*@Override + public @NotNull ItemStack assemble(CultivatorRecipeInput input, HolderLookup.Provider registries) { + return getWeightedResult(registries); + } + + @Override + public @NotNull ItemStack getResultItem(HolderLookup.Provider registries) { + return output.copy(); + } + *///?} else { + @Override + public ItemStack assemble(CultivatorRecipeInput input, RegistryAccess registries) { + return getWeightedResult(registries); + } + + @Override + public ItemStack getResultItem(RegistryAccess registries) { + return output.copy(); + } + + @Override + public ResourceLocation getId() { + return id; + } + //?} + + private ItemStack getWeightedResult(Object registries) { + //? if >1.20.1 { + /*var fossilTag = BuiltInRegistries.ITEM.getOrCreateTag(ModTags.Items.FOSSILS); + List candidates = fossilTag.stream().map(ItemStack::new).toList(); + *///?} else { + ItemStack[] candidatesArr = Ingredient.of(ModTags.Items.FOSSILS).getItems(); + List candidates = List.of(candidatesArr); + //?} + + if (candidates.isEmpty()) return output.copy(); + + RandomSource random = RandomSource.create(); + long total = 0; + int[] weightsArray = new int[candidates.size()]; + for (int i = 0; i < candidates.size(); i++) { + Item item = candidates.get(i).getItem(); + ResourceLocation key = BuiltInRegistries.ITEM.getKey(item); + int w = Math.max(0, weights.getOrDefault(key, 1)); + weightsArray[i] = w; + total += w; + } + + if (total <= 0) return candidates.get(random.nextInt(candidates.size())).copy(); + + long roll = 1L + (total <= Integer.MAX_VALUE ? random.nextInt((int) total) : Math.abs(random.nextLong()) % total); + long cumulative = 0; + for (int i = 0; i < candidates.size(); i++) { + cumulative += weightsArray[i]; + if (roll <= cumulative) return candidates.get(i).copy(); + } + return candidates.get(candidates.size() - 1).copy(); + } + + @Override + public boolean canCraftInDimensions(int width, int height) { + return true; + } + + @Override + public @NotNull NonNullList getIngredients() { + return inputs; + } + + @Override + public @NotNull RecipeSerializer getSerializer() { + return ModRecipes.CULTIVATOR_SERIALIZER.get(); + } + + @Override + public @NotNull RecipeType getType() { + return ModRecipes.CULTIVATOR_RECIPE_TYPE.get(); + } + + public int getWeightFor(Item item) { + ResourceLocation key = BuiltInRegistries.ITEM.getKey(item); + return weights.getOrDefault(key, 1); + } + + //? if <=1.20.1 { + public ItemStack output() { return output; } + //?} + + //? if >1.20.1 { + /*public Map weights() { return weights; } + public ItemStack output() { return output; } + *///?} + + public static class Serializer implements RecipeSerializer { + //? if >1.20.1 { + /*private static final Codec> WEIGHTS_CODEC = + Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT); + + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( + Ingredient.CODEC_NONEMPTY.listOf().fieldOf("ingredients").flatXmap(list -> { + if (list.size() != 1) return DataResult.error(() -> "Must have 1 ingredient"); + return DataResult.success(NonNullList.of(Ingredient.EMPTY, list.toArray(Ingredient[]::new))); + }, DataResult::success).forGetter(CultivatorRecipe::inputs), + ItemStack.CODEC.fieldOf("result").forGetter(CultivatorRecipe::output), + WEIGHTS_CODEC.optionalFieldOf("fossil_weights", Map.of()).forGetter(CultivatorRecipe::weights) + ).apply(inst, CultivatorRecipe::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, recipe) -> { + ByteBufCodecs.collection(NonNullList::createWithCapacity, Ingredient.CONTENTS_STREAM_CODEC).encode(buf, recipe.inputs()); + ItemStack.STREAM_CODEC.encode(buf, recipe.output()); + buf.writeMap(recipe.weights(), ResourceLocation.STREAM_CODEC, ByteBufCodecs.VAR_INT); + }, + buf -> { + NonNullList inputs = ByteBufCodecs.collection(NonNullList::createWithCapacity, Ingredient.CONTENTS_STREAM_CODEC).decode(buf); + ItemStack output = ItemStack.STREAM_CODEC.decode(buf); + Map weights = buf.readMap( + HashMap::new, + ResourceLocation.STREAM_CODEC, + ByteBufCodecs.VAR_INT + ); + return new CultivatorRecipe(inputs, output, weights); + } + ); + + @Override public MapCodec codec() { return CODEC; } + @Override public StreamCodec streamCodec() { return STREAM_CODEC; } + *///?} else { + @Override + public CultivatorRecipe fromJson(ResourceLocation id, JsonObject json) { + ItemStack output = ShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(json, "result")); + JsonArray ingredients = GsonHelper.getAsJsonArray(json, "ingredients"); + NonNullList inputs = NonNullList.withSize(1, Ingredient.EMPTY); + inputs.set(0, Ingredient.fromJson(ingredients.get(0))); + Map weights = new HashMap<>(); + if (json.has("fossil_weights")) { + JsonObject weightsObj = json.getAsJsonObject("fossil_weights"); + for (String key : weightsObj.keySet()) { + weights.put(ResourceLocation.tryParse(key), weightsObj.get(key).getAsInt()); + } + } + return new CultivatorRecipe(id, inputs, output, weights); + } + + @Override + public CultivatorRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buf) { + int size = buf.readVarInt(); + NonNullList inputs = NonNullList.withSize(size, Ingredient.EMPTY); + for (int i = 0; i < size; i++) { + inputs.set(i, Ingredient.fromNetwork(buf)); + } + ItemStack output = buf.readItem(); + Map weights = buf.readMap(FriendlyByteBuf::readResourceLocation, FriendlyByteBuf::readVarInt); + return new CultivatorRecipe(id, inputs, output, weights); + } + + @Override + public void toNetwork(FriendlyByteBuf buf, CultivatorRecipe recipe) { + buf.writeVarInt(recipe.inputs.size()); + for (Ingredient ing : recipe.inputs) { + ing.toNetwork(buf); + } + buf.writeItem(recipe.output); + buf.writeMap(recipe.weights, FriendlyByteBuf::writeResourceLocation, FriendlyByteBuf::writeVarInt); + } + //?} + } +} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipeInput.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipeInput.java new file mode 100644 index 0000000..1195915 --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/CultivatorRecipeInput.java @@ -0,0 +1,35 @@ +package net.cmr.jurassicrevived.recipe; + +import net.minecraft.world.item.ItemStack; +//? if >1.20.1 { +/*import net.minecraft.world.item.crafting.RecipeInput; + *///?} else { +import net.minecraft.world.SimpleContainer; + //?} + +import java.util.List; + + +//? if >1.20.1 { +/*public record CultivatorRecipeInput(ItemStack fossil, ItemStack waterSlot) implements RecipeInput { + @Override + public ItemStack getItem(int index) { + return switch (index) { + case 0 -> fossil; + case 1 -> waterSlot; + default -> throw new IllegalArgumentException("Unexpected slot index: " + index); + }; + } + + @Override + public int size() { + return 2; + } +} +*///?} else { +public class CultivatorRecipeInput extends SimpleContainer { + public CultivatorRecipeInput(ItemStack fossil, ItemStack waterSlot) { + super(fossil, waterSlot); + } +} +//?} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAAnalyzerRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAAnalyzerRecipe.java index 0098531..1ed8865 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAAnalyzerRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAAnalyzerRecipe.java @@ -55,6 +55,16 @@ public record DNAAnalyzerRecipe( return output.copy(); } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + @Override public ItemStack getResultItem(HolderLookup.Provider provider) { return output.copy(); diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAExtractorRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAExtractorRecipe.java index 69ba22c..4e7994f 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAExtractorRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAExtractorRecipe.java @@ -94,6 +94,16 @@ public record DNAExtractorRecipe( @Override public RecipeSerializer getSerializer() { return ModRecipes.DNA_EXTRACTOR_SERIALIZER.get(); } @Override public RecipeType getType() { return ModRecipes.DNA_EXTRACTOR_RECIPE_TYPE.get(); } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + public int getWeightFor(Item item) { ResourceLocation key = BuiltInRegistries.ITEM.getKey(item); return weights.getOrDefault(key, 1); diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAHybridizerRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAHybridizerRecipe.java index e69ecc5..0eb54be 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAHybridizerRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/DNAHybridizerRecipe.java @@ -35,6 +35,16 @@ public record DNAHybridizerRecipe(ResourceLocation id, NonNullList i return inputs; } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + @Override public boolean matches(DNAHybridizerRecipeInput recipeInput, Level level) { if (level.isClientSide) return false; diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryoCalcificationMachineRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryoCalcificationMachineRecipe.java index 76b63b3..f66aea8 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryoCalcificationMachineRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryoCalcificationMachineRecipe.java @@ -33,6 +33,16 @@ public record EmbryoCalcificationMachineRecipe(ResourceLocation id, NonNullList< return inputs; } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + @Override public boolean matches(EmbryoCalcificationMachineRecipeInput recipeInput, Level level) { if (level.isClientSide) return false; diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryonicMachineRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryonicMachineRecipe.java index 3b9eec0..da544bc 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryonicMachineRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/EmbryonicMachineRecipe.java @@ -76,6 +76,16 @@ public class EmbryonicMachineRecipe implements Recipe { return getWeightedResult(registries); } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + @Override public @NotNull ItemStack getResultItem(HolderLookup.Provider registries) { return output.copy(); diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/FossilGrinderRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/FossilGrinderRecipe.java index f667bd1..3a7f75a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/FossilGrinderRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/FossilGrinderRecipe.java @@ -59,6 +59,16 @@ public class FossilGrinderRecipe implements Recipe { return inputs.get(0).test(input.getItem(0)); } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + //? if >1.20.1 { /*@Override public @NotNull ItemStack assemble(FossilGrinderRecipeInput input, HolderLookup.Provider registries) { diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/IncubatorRecipe.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/IncubatorRecipe.java index 4770bc3..4b9f77a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/IncubatorRecipe.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/IncubatorRecipe.java @@ -49,6 +49,16 @@ public class IncubatorRecipe implements Recipe { return inputs.get(0).test(input.getItem(0)); } + @Override + public boolean isSpecial() { + return true; + } + + @Override + public boolean showNotification() { + return false; + } + //? if >1.20.1 { /*@Override public @NotNull ItemStack assemble(IncubatorRecipeInput input, HolderLookup.Provider registries) { diff --git a/common/src/main/java/net/cmr/jurassicrevived/recipe/ModRecipes.java b/common/src/main/java/net/cmr/jurassicrevived/recipe/ModRecipes.java index 9009d23..1cb32ca 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/recipe/ModRecipes.java +++ b/common/src/main/java/net/cmr/jurassicrevived/recipe/ModRecipes.java @@ -93,6 +93,16 @@ public class ModRecipes { } }); + public static final RegistrySupplier> CULTIVATOR_SERIALIZER = + SERIALIZERS.register("cultivating", CultivatorRecipe.Serializer::new); + public static final RegistrySupplier> CULTIVATOR_RECIPE_TYPE = + TYPES.register("cultivating", () -> new RecipeType() { + @Override + public String toString() { + return "cultivating"; + } + }); + public static void register() { SERIALIZERS.register(); TYPES.register(); diff --git a/common/src/main/java/net/cmr/jurassicrevived/screen/ModMenuTypes.java b/common/src/main/java/net/cmr/jurassicrevived/screen/ModMenuTypes.java index 5dcdbf3..10c2354 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/screen/ModMenuTypes.java +++ b/common/src/main/java/net/cmr/jurassicrevived/screen/ModMenuTypes.java @@ -30,6 +30,8 @@ public class ModMenuTypes { MENUS.register("embryo_calcification_machine_menu", () -> MenuRegistry.ofExtended(EmbryoCalcificationMachineMenu::new)); public static final RegistrySupplier> INCUBATOR_MENU = MENUS.register("incubator_menu", () -> MenuRegistry.ofExtended(IncubatorMenu::new)); + public static final RegistrySupplier> CULTIVATOR_MENU = + MENUS.register("cultivator_menu", () -> MenuRegistry.ofExtended(CultivatorMenu::new)); public static final RegistrySupplier> TANK_MENU = MENUS.register("tank_menu", () -> MenuRegistry.ofExtended(TankMenu::new)); public static final RegistrySupplier> POWER_CELL_MENU = diff --git a/common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorMenu.java b/common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorMenu.java new file mode 100644 index 0000000..4bccbda --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorMenu.java @@ -0,0 +1,146 @@ +package net.cmr.jurassicrevived.screen.custom; + +import net.cmr.jurassicrevived.block.ModBlocks; +import net.cmr.jurassicrevived.block.entity.custom.CultivatorBlockEntity; +import net.cmr.jurassicrevived.screen.ModMenuTypes; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.*; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; + +public class CultivatorMenu extends AbstractContainerMenu { + public final CultivatorBlockEntity blockEntity; + public final Level level; + public final ContainerData data; + + public CultivatorMenu(int containerId, Inventory inventory, FriendlyByteBuf data) { + this(containerId, inventory, inventory.player.level().getBlockEntity(data.readBlockPos()), new SimpleContainerData(2)); + } + + public CultivatorMenu(int containerId, Inventory inventory, BlockEntity entity, ContainerData data) { + super(ModMenuTypes.CULTIVATOR_MENU.get(), containerId); + blockEntity = ((CultivatorBlockEntity) entity); + this.level = inventory.player.level(); + this.data = data; + + addPlayerInventory(inventory); + addPlayerHotbar(inventory); + + // Water Input Slot (0) + this.addSlot(new Slot(blockEntity.itemHandler, 0, 7, 61) { + @Override + public boolean mayPlace(ItemStack stack) { + // Simplified validation for common: accepts bucket or water bucket + return stack.is(Items.WATER_BUCKET); + } + }); + + // Fossil Block Slot (1) + this.addSlot(new Slot(blockEntity.itemHandler, 1, 56, 35) { + @Override + public boolean mayPlace(ItemStack stack) { + return stack.getItem() == ModBlocks.STONE_FOSSIL.get().asItem() || stack.getItem() == ModBlocks.DEEPSLATE_FOSSIL.get().asItem(); + } + }); + + // Output Slots (2, 3, 4) + this.addSlot(new Slot(blockEntity.itemHandler, 2, 103, 35) { + @Override + public boolean mayPlace(ItemStack stack) { + return false; + } + }); + this.addSlot(new Slot(blockEntity.itemHandler, 3, 121, 35) { + @Override + public boolean mayPlace(ItemStack stack) { + return false; + } + }); + this.addSlot(new Slot(blockEntity.itemHandler, 4, 139, 35) { + @Override + public boolean mayPlace(ItemStack stack) { + return false; + } + }); + + addDataSlots(data); + } + + public boolean isCrafting() { + return data.get(0) > 0; + } + + public int getScaledArrowProgress() { + int progress = this.data.get(0); + int maxProgress = this.data.get(1); + int arrowPixelSize = 29; + + return maxProgress != 0 && progress != 0 ? progress * arrowPixelSize / maxProgress : 0; + } + + private static final int HOTBAR_SLOT_COUNT = 9; + private static final int PLAYER_INVENTORY_ROW_COUNT = 3; + private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9; + private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT; + private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT; + private static final int VANILLA_FIRST_SLOT_INDEX = 0; + private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_SLOT_COUNT; + private static final int TE_INVENTORY_SLOT_COUNT = 5; + + @Override + public ItemStack quickMoveStack(Player playerIn, int pIndex) { + Slot sourceSlot = slots.get(pIndex); + if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; + ItemStack sourceStack = sourceSlot.getItem(); + ItemStack copyOfSourceStack = sourceStack.copy(); + + if (pIndex < VANILLA_SLOT_COUNT) { + // Player inventory -> machine inputs (slots 0 and 1) + int teInputStart = TE_INVENTORY_FIRST_SLOT_INDEX; + int teInputEndExclusive = TE_INVENTORY_FIRST_SLOT_INDEX + 2; + if (!moveItemStackTo(sourceStack, teInputStart, teInputEndExclusive, false)) { + return ItemStack.EMPTY; + } + } else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) { + // Machine -> player inventory + if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_SLOT_COUNT, false)) { + return ItemStack.EMPTY; + } + } else { + return ItemStack.EMPTY; + } + + if (sourceStack.isEmpty()) { + sourceSlot.set(ItemStack.EMPTY); + } else { + sourceSlot.setChanged(); + } + sourceSlot.onTake(playerIn, sourceStack); + return copyOfSourceStack; + } + + @Override + public boolean stillValid(Player player) { + return stillValid(ContainerLevelAccess.create(this.level, this.blockEntity.getBlockPos()), + player, this.blockEntity.getBlockState().getBlock()); + } + + public void addPlayerInventory(Inventory playerInventory) { + for (int i = 0; i < 3; i++) { + for (int l = 0; l < 9; l++) { + this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18)); + } + } + } + + public void addPlayerHotbar(Inventory playerInventory) { + for (int i = 0; i < 9; i++) { + this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142)); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorScreen.java b/common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorScreen.java new file mode 100644 index 0000000..527726e --- /dev/null +++ b/common/src/main/java/net/cmr/jurassicrevived/screen/custom/CultivatorScreen.java @@ -0,0 +1,142 @@ +package net.cmr.jurassicrevived.screen.custom; + +import com.mojang.blaze3d.systems.RenderSystem; +import dev.architectury.fluid.FluidStack; +import net.cmr.jurassicrevived.Constants; +import net.cmr.jurassicrevived.config.JRConfigManager; +import net.cmr.jurassicrevived.screen.renderer.EnergyDisplayTooltipArea; +import net.cmr.jurassicrevived.screen.renderer.FluidTankRenderer; +import net.cmr.jurassicrevived.util.MouseUtil; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.TooltipFlag; + +import java.util.Optional; + +public class CultivatorScreen extends AbstractContainerScreen { + private static final ResourceLocation GUI_TEXTURE = + Constants.rl("textures/gui/fossil_cleaner/fossil_cleaner_gui.png"); + private static final ResourceLocation BUBBLES_TEXTURE = + Constants.rl("textures/gui/generic/bubbles.png"); + private static final ResourceLocation WHITE_BUBBLES_TEXTURE = + Constants.rl("textures/gui/generic/white_bubbles.png"); + private static final ResourceLocation POWER_BAR_TEXTURE = + Constants.rl("textures/gui/generic/power_bar.png"); + private static final ResourceLocation SKULL_TEXTURE = + Constants.rl("textures/gui/generic/skull.png"); + private FluidTankRenderer fluidRenderer; + private EnergyDisplayTooltipArea energyInfoArea; + + public CultivatorScreen(CultivatorMenu menu, Inventory playerInventory, Component title) { + super(menu, playerInventory, title); + } + + @Override + protected void init() { + super.init(); + + this.inventoryLabelY = 10000; + this.titleLabelY = 10000; + + assignFluidRenderer(); + assignEnergyInfoArea(); + } + + private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) { + if(isMouseAboveArea(pMouseX, pMouseY, x, y, 160, 11, 8, 64) && JRConfigManager.get().requirePower) { + guiGraphics.renderTooltip(this.font, energyInfoArea.getTooltips(), + Optional.empty(), pMouseX - x, pMouseY - y); + } + } + + private void assignEnergyInfoArea() { + energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 160, + ((height - imageHeight) / 2) + 11, menu.blockEntity.getEnergyStorage(null)); + } + + private void assignFluidRenderer() { + fluidRenderer = new FluidTankRenderer(16000, true, 16, 50); + } + + private void renderFluidTooltipArea(GuiGraphics guiGraphics, int MouseX, int MouseY, int x, int y, + FluidStack stack, int offsetX, int offsetY, FluidTankRenderer renderer) { + if(isMouseAboveArea(MouseX, MouseY, x, y, offsetX, offsetY, renderer)) { + guiGraphics.renderTooltip(this.font, renderer.getTooltip(stack, TooltipFlag.Default.NORMAL), + Optional.empty(), MouseX - x, MouseY - y); + } + } + + @Override + protected void renderLabels(GuiGraphics guiGraphics, int pMouseX, int pMouseY) { + int x = (width - imageWidth) / 2; + int y = (height - imageHeight) / 2; + + renderFluidTooltipArea(guiGraphics, pMouseX, pMouseY, x, y, menu.blockEntity.getFluid(), 7, 8, fluidRenderer); + if (JRConfigManager.get().requirePower) { + renderEnergyAreaTooltip(guiGraphics, pMouseX, pMouseY, x, y); + } + } + + @Override + protected void renderBg(GuiGraphics guiGraphics, float v, int i, int i1) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, GUI_TEXTURE); + int x = (this.width - this.imageWidth) / 2; + int y = (this.height - this.imageHeight) /2; + + guiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, this.imageWidth, this.imageHeight, 176, 166); + guiGraphics.blit(BUBBLES_TEXTURE, x + 73, y + 37, 0, 0, 29, 12, 29, 12); + guiGraphics.blit(SKULL_TEXTURE, x + 57, y + 35, 0, 0, 16, 16, 16, 16); + RenderProgressArrow(guiGraphics, x, y); + + if (JRConfigManager.get().requirePower) { + guiGraphics.blit(POWER_BAR_TEXTURE, x+159, y+10, 0, 0, 10, 66, 10, 66); + } + } + + private void RenderProgressArrow(GuiGraphics guiGraphics, int x, int y) { + if(menu.isCrafting()) { + guiGraphics.blit(WHITE_BUBBLES_TEXTURE, x+73, y + 37, 0, 0, menu.getScaledArrowProgress(), 12, 29, 12); + } + } + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + //? if >1.20.1 { + /*this.renderBackground(guiGraphics, mouseX, mouseY, partialTick); + *///?} else { + renderBackground(guiGraphics); + //?} + super.render(guiGraphics, mouseX, mouseY, partialTick); + int x = (this.width - this.imageWidth) / 2; + int y = (this.height - this.imageHeight) /2; + if (MouseUtil.isMouseOver(mouseX, mouseY, x + 7, y + 8, 16, 50)) { + renderHoverHighlight(guiGraphics, x + 7, y + 8, 16, 50); + } + renderTooltip(guiGraphics, mouseX, mouseY); + fluidRenderer.render(guiGraphics, x + 7, y + 8, menu.blockEntity.getFluid()); + if (JRConfigManager.get().requirePower) { + energyInfoArea.render(guiGraphics); + } + } + + private static void renderHoverHighlight(GuiGraphics g, int x, int y, int w, int h) { + g.pose().pushPose(); + g.pose().translate(0, 0, 200); + g.fillGradient(x, y, x + w, y + h, 0x80FFFFFF, 0x80FFFFFF); + g.pose().popPose(); + } + + public static boolean isMouseAboveArea(int pMouseX, int pMouseY, int x, int y, int offsetX, int offsetY, FluidTankRenderer renderer) { + return MouseUtil.isMouseOver(pMouseX, pMouseY, x + offsetX, y + offsetY, renderer.getWidth(), renderer.getHeight()); + } + + public static boolean isMouseAboveArea(int pMouseX, int pMouseY, int x, int y, int offsetX, int offsetY, int width, int height) { + return MouseUtil.isMouseOver(pMouseX, pMouseY, x + offsetX, y + offsetY, width, height); + } +} \ No newline at end of file diff --git a/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModSpawnDefinitions.java b/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModSpawnDefinitions.java index b6969e5..2e05feb 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModSpawnDefinitions.java +++ b/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModSpawnDefinitions.java @@ -88,7 +88,10 @@ public final class ModSpawnDefinitions { spawn("utahraptor", ModEntities.UTAHRAPTOR, 4, 1, 3, BiomeTags.IS_TAIGA, BiomeTags.IS_FOREST), spawn("velociraptor", ModEntities.VELOCIRAPTOR, 5, 2, 4, BiomeTags.IS_BADLANDS, BiomeTags.IS_OVERWORLD), spawn("zhenyuanopterus", ModEntities.ZHENYUANOPTERUS, 2, 2, 5, BiomeTags.IS_BEACH, BiomeTags.IS_MOUNTAIN), - spawn("achillobator", ModEntities.ACHILLOBATOR, 3, 1, 2, BiomeTags.IS_TAIGA) + spawn("achillobator", ModEntities.ACHILLOBATOR, 3, 1, 2, BiomeTags.IS_TAIGA), + spawn("coelacanth", ModEntities.COELACANTH, 9, 3, 6, BiomeTags.IS_OCEAN, BiomeTags.IS_RIVER), + spawn("mawsonia", ModEntities.MAWSONIA, 3, 1, 2, BiomeTags.IS_OCEAN, BiomeTags.IS_RIVER), + spawn("alligator_gar", ModEntities.ALLIGATOR_GAR, 6, 1, 2, BiomeTags.IS_OCEAN, BiomeTags.IS_RIVER) ); @SafeVarargs diff --git a/common/src/main/resources/assets/jurassicrevived/lang/en_us.json b/common/src/main/resources/assets/jurassicrevived/lang/en_us.json index 7ff0dff..dee9c6c 100755 --- a/common/src/main/resources/assets/jurassicrevived/lang/en_us.json +++ b/common/src/main/resources/assets/jurassicrevived/lang/en_us.json @@ -85,6 +85,9 @@ "item.jurassicrevived.chilesaurus_spawn_egg": "Chilesaurus Spawn Egg", "item.jurassicrevived.thescelosaurus_spawn_egg": "Thescelosaurus Spawn Egg", "item.jurassicrevived.mussasaurus_spawn_egg": "Mussasaurus Spawn Egg", + "item.jurassicrevived.coelacanth_spawn_egg": "Coelacanth Spawn Egg", + "item.jurassicrevived.mawsonia_spawn_egg": "Mawsonia Spawn Egg", + "item.jurassicrevived.alligator_gar_spawn_egg": "Alligator Gar Spawn Egg", "entity.jurassicrevived.apatosaurus": "Apatosaurus", "entity.jurassicrevived.albertosaurus": "Albertosaurus", @@ -166,6 +169,9 @@ "entity.jurassicrevived.chilesaurus": "Chilesaurus", "entity.jurassicrevived.thescelosaurus": "Thescelosaurus", "entity.jurassicrevived.mussasaurus": "Mussasaurus", + "entity.jurassicrevived.coelacanth": "Coelacanth", + "entity.jurassicrevived.mawsonia": "Mawsonia", + "entity.jurassicrevived.alligator_gar": "Alligator Gar", "block.jurassicrevived.cat_plushie": "Cat Plushie", "block.jurassicrevived.trash_can": "Trash Can", @@ -238,6 +244,7 @@ "block.jurassicrevived.embryonic_machine": "Embryonic Machine", "block.jurassicrevived.embryo_calcification_machine": "Embryo Calcification Machine", "block.jurassicrevived.incubator": "Incubator", + "block.jurassicrevived.cultivator": "Cultivator", "block.jurassicrevived.white_generator": "White Generator", "block.jurassicrevived.white_dna_extractor": "White DNA Extractor", @@ -248,6 +255,7 @@ "block.jurassicrevived.white_embryonic_machine": "White Embryonic Machine", "block.jurassicrevived.white_embryo_calcification_machine": "White Embryo Calcification Machine", "block.jurassicrevived.white_incubator": "White Incubator", + "block.jurassicrevived.white_cultivator": "White Cultivator", "block.jurassicrevived.stone_fossil": "Stone Fossil", "block.jurassicrevived.deepslate_fossil": "Deepslate Fossil", @@ -344,6 +352,9 @@ "item.jurassicrevived.chilesaurus_skull_fossil": "Chilesaurus Skull Fossil", "item.jurassicrevived.thescelosaurus_skull_fossil": "Thescelosaurus Skull Fossil", "item.jurassicrevived.mussasaurus_skull_fossil": "Mussasaurus Skull Fossil", + "item.jurassicrevived.coelacanth_skull_fossil": "Coelacanth Skull Fossil", + "item.jurassicrevived.mawsonia_skull_fossil": "Mawsonia Skull Fossil", + "item.jurassicrevived.alligator_gar_skull_fossil": "Alligator Gar Skull Fossil", "item.jurassicrevived.fresh_velociraptor_skull": "Fresh Velociraptor Skull", "item.jurassicrevived.fresh_tyrannosaurus_rex_skull": "Fresh Tyrannosaurus Rex Skull", @@ -423,6 +434,9 @@ "item.jurassicrevived.fresh_chilesaurus_skull": "Fresh Chilesaurus Skull", "item.jurassicrevived.fresh_thescelosaurus_skull": "Fresh Thescelosaurus Skull", "item.jurassicrevived.fresh_mussasaurus_skull": "Fresh Mussasaurus Skull", + "item.jurassicrevived.fresh_coelacanth_skull": "Fresh Coelacanth Skull", + "item.jurassicrevived.fresh_mawsonia_skull": "Fresh Mawsonia Skull", + "item.jurassicrevived.fresh_alligator_gar_skull": "Fresh Alligator Gar Skull", "item.jurassicrevived.test_tube": "Test Tube", "item.jurassicrevived.syringe": "Syringe", @@ -518,6 +532,9 @@ "item.jurassicrevived.chilesaurus_tissue": "Chilesaurus Tissue", "item.jurassicrevived.thescelosaurus_tissue": "Thescelosaurus Tissue", "item.jurassicrevived.mussasaurus_tissue": "Mussasaurus Tissue", + "item.jurassicrevived.coelacanth_tissue": "Coelacanth Tissue", + "item.jurassicrevived.mawsonia_tissue": "Mawsonia Tissue", + "item.jurassicrevived.alligator_gar_tissue": "Alligator Gar Tissue", "item.jurassicrevived.velociraptor_dna": "Velociraptor DNA", "item.jurassicrevived.tyrannosaurus_rex_dna": "Tyrannosaurus Rex DNA", @@ -597,6 +614,9 @@ "item.jurassicrevived.chilesaurus_dna": "Chilesaurus DNA", "item.jurassicrevived.thescelosaurus_dna": "Thescelosaurus DNA", "item.jurassicrevived.mussasaurus_dna": "Mussasaurus DNA", + "item.jurassicrevived.coelacanth_dna": "Coelacanth DNA", + "item.jurassicrevived.mawsonia_dna": "Mawsonia DNA", + "item.jurassicrevived.alligator_gar_dna": "Alligator Gar DNA", "item.jurassicrevived.velociraptor_syringe": "Velociraptor Syringe", "item.jurassicrevived.tyrannosaurus_rex_syringe": "Tyrannosaurus Rex Syringe", @@ -676,6 +696,9 @@ "item.jurassicrevived.chilesaurus_syringe": "Chilesaurus Syringe", "item.jurassicrevived.thescelosaurus_syringe": "Thescelosaurus Syringe", "item.jurassicrevived.mussasaurus_syringe": "Mussasaurus Syringe", + "item.jurassicrevived.coelacanth_syringe": "Coelacanth Syringe", + "item.jurassicrevived.mawsonia_syringe": "Mawsonia Syringe", + "item.jurassicrevived.alligator_gar_syringe": "Alligator Gar Syringe", "block.jurassicrevived.velociraptor_egg": "Velociraptor Egg", "block.jurassicrevived.tyrannosaurus_rex_egg": "Tyrannosaurus Rex Egg", @@ -755,6 +778,9 @@ "block.jurassicrevived.chilesaurus_egg": "Chilesaurus Egg", "block.jurassicrevived.thescelosaurus_egg": "Thescelosaurus Egg", "block.jurassicrevived.mussasaurus_egg": "Mussasaurus Egg", + "block.jurassicrevived.coelacanth_egg": "Coelacanth Egg", + "block.jurassicrevived.mawsonia_egg": "Mawsonia Egg", + "block.jurassicrevived.alligator_gar_egg": "Alligator Gar Egg", "block.jurassicrevived.incubated_velociraptor_egg": "§aIncubated Velociraptor Egg", "block.jurassicrevived.incubated_tyrannosaurus_rex_egg": "§aIncubated Tyrannosaurus Rex Egg", diff --git a/common/src/main/resources/assets/jurassicrevived/models/block/cultivator.json b/common/src/main/resources/assets/jurassicrevived/models/block/cultivator.json new file mode 100644 index 0000000..b4f4bf5 --- /dev/null +++ b/common/src/main/resources/assets/jurassicrevived/models/block/cultivator.json @@ -0,0 +1,174 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "ambientocclusion": false, + "render_type": "cutout", + "texture_size": [128, 128], + "textures": { + "1": "jurassicrevived:block/cultivator", + "particle": "jurassicrevived:block/cultivator" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [6, 5.5, 8, 5.75], "texture": "#1"}, + "east": {"uv": [6, 5.75, 8, 6], "texture": "#1"}, + "south": {"uv": [6, 6, 8, 6.25], "texture": "#1"}, + "west": {"uv": [6, 6.25, 8, 6.5], "texture": "#1"}, + "up": {"uv": [6, 2, 4, 0], "texture": "#1"}, + "down": {"uv": [6, 2, 4, 4], "texture": "#1"} + } + }, + { + "from": [0, 2, 0], + "to": [1, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 0]}, + "faces": { + "north": {"uv": [6, 6.75, 6.125, 10.25], "texture": "#1"}, + "east": {"uv": [6.125, 6.75, 6.25, 10.25], "texture": "#1"}, + "south": {"uv": [6.25, 6.75, 6.375, 10.25], "texture": "#1"}, + "west": {"uv": [6.375, 6.75, 6.5, 10.25], "texture": "#1"}, + "up": {"uv": [8, 8, 7.875, 7.875], "texture": "#1"}, + "down": {"uv": [8.125, 0, 8, 0.125], "texture": "#1"} + } + }, + { + "from": [0, 2, 15], + "to": [1, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 15]}, + "faces": { + "north": {"uv": [6.5, 6.75, 6.625, 10.25], "texture": "#1"}, + "east": {"uv": [6.625, 6.75, 6.75, 10.25], "texture": "#1"}, + "south": {"uv": [6.75, 6.75, 6.875, 10.25], "texture": "#1"}, + "west": {"uv": [6.875, 6.75, 7, 10.25], "texture": "#1"}, + "up": {"uv": [8.125, 0.25, 8, 0.125], "texture": "#1"}, + "down": {"uv": [8.125, 0.25, 8, 0.375], "texture": "#1"} + } + }, + { + "from": [15, 2, 15], + "to": [16, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 15]}, + "faces": { + "north": {"uv": [7, 6.75, 7.125, 10.25], "texture": "#1"}, + "east": {"uv": [7.125, 6.75, 7.25, 10.25], "texture": "#1"}, + "south": {"uv": [0, 7.25, 0.125, 10.75], "texture": "#1"}, + "west": {"uv": [0.125, 7.25, 0.25, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.5, 8, 0.375], "texture": "#1"}, + "down": {"uv": [8.125, 0.5, 8, 0.625], "texture": "#1"} + } + }, + { + "from": [15, 2, 0], + "to": [16, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 0]}, + "faces": { + "north": {"uv": [0.25, 7.25, 0.375, 10.75], "texture": "#1"}, + "east": {"uv": [0.375, 7.25, 0.5, 10.75], "texture": "#1"}, + "south": {"uv": [0.5, 7.25, 0.625, 10.75], "texture": "#1"}, + "west": {"uv": [0.625, 7.25, 0.75, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.75, 8, 0.625], "texture": "#1"}, + "down": {"uv": [0.875, 8, 0.75, 8.125], "texture": "#1"} + } + }, + { + "from": [0.15, 1.65, 0.15], + "to": [15.85, 30.35, 15.85], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 1.5, 0]}, + "faces": { + "north": {"uv": [0, 0, 2, 3.625], "texture": "#1"}, + "east": {"uv": [2, 0, 4, 3.625], "texture": "#1"}, + "south": {"uv": [0, 3.625, 2, 7.25], "texture": "#1"}, + "west": {"uv": [2, 3.625, 4, 7.25], "texture": "#1"}, + "up": {"uv": [6, 6, 4, 4], "texture": "#1"}, + "down": {"uv": [8, 0, 6, 2], "texture": "#1"} + } + }, + { + "from": [0, 30, 0], + "to": [16, 32, 16], + "faces": { + "north": {"uv": [6, 6.5, 8, 6.75], "texture": "#1"}, + "east": {"uv": [6.75, 4, 8.75, 4.25], "texture": "#1"}, + "south": {"uv": [6.75, 4.25, 8.75, 4.5], "texture": "#1"}, + "west": {"uv": [6.75, 4.5, 8.75, 4.75], "texture": "#1"}, + "up": {"uv": [8, 4, 6, 2], "texture": "#1"}, + "down": {"uv": [6, 6, 4, 8], "texture": "#1"} + } + }, + { + "from": [5, 28, 5], + "to": [11, 30, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -2, 0]}, + "faces": { + "north": {"uv": [1.5, 7.25, 2.25, 7.5], "texture": "#1"}, + "east": {"uv": [2.25, 7.25, 3, 7.5], "texture": "#1"}, + "south": {"uv": [3, 7.25, 3.75, 7.5], "texture": "#1"}, + "west": {"uv": [7.25, 6.75, 8, 7], "texture": "#1"}, + "up": {"uv": [6.75, 4.75, 6, 4], "texture": "#1"}, + "down": {"uv": [6.75, 4.75, 6, 5.5], "texture": "#1"} + } + }, + { + "from": [7.5, 22, 7.5], + "to": [8.5, 28, 8.5], + "rotation": {"angle": 0, "axis": "y", "origin": [0.5, -4, -0.5]}, + "faces": { + "north": {"uv": [7.5, 7.75, 7.625, 8.5], "texture": "#1"}, + "east": {"uv": [7.625, 7.75, 7.75, 8.5], "texture": "#1"}, + "south": {"uv": [7.75, 7.75, 7.875, 8.5], "texture": "#1"}, + "west": {"uv": [2, 7.875, 2.125, 8.625], "texture": "#1"}, + "up": {"uv": [8.125, 0.875, 8, 0.75], "texture": "#1"}, + "down": {"uv": [1, 8, 0.875, 8.125], "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_lefthand": { + "rotation": [0, -135, 0], + "scale": [0.2, 0.2, 0.2] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, -135, 0], + "translation": [0, -3, 0], + "scale": [0.4, 0.4, 0.4] + }, + "head": { + "translation": [0, 10, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "translation": [0, -4, 0], + "scale": [0.5, 0.5, 0.5] + } + }, + "groups": [ + { + "name": "group", + "origin": [8, 8, 8], + "scope": 0, + "color": 0, + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8] + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/jurassicrevived/models/block/cultivator_lit.json b/common/src/main/resources/assets/jurassicrevived/models/block/cultivator_lit.json new file mode 100644 index 0000000..47849c0 --- /dev/null +++ b/common/src/main/resources/assets/jurassicrevived/models/block/cultivator_lit.json @@ -0,0 +1,295 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "ambientocclusion": false, + "render_type": "cutout", + "texture_size": [128, 128], + "textures": { + "1": "jurassicrevived:block/cultivator_lit", + "particle": "jurassicrevived:block/cultivator_lit" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [6, 5.5, 8, 5.75], "texture": "#1"}, + "east": {"uv": [6, 5.75, 8, 6], "texture": "#1"}, + "south": {"uv": [6, 6, 8, 6.25], "texture": "#1"}, + "west": {"uv": [6, 6.25, 8, 6.5], "texture": "#1"}, + "up": {"uv": [6, 2, 4, 0], "texture": "#1"}, + "down": {"uv": [6, 2, 4, 4], "texture": "#1"} + } + }, + { + "from": [0, 2, 0], + "to": [1, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 0]}, + "faces": { + "north": {"uv": [6, 6.75, 6.125, 10.25], "texture": "#1"}, + "east": {"uv": [6.125, 6.75, 6.25, 10.25], "texture": "#1"}, + "south": {"uv": [6.25, 6.75, 6.375, 10.25], "texture": "#1"}, + "west": {"uv": [6.375, 6.75, 6.5, 10.25], "texture": "#1"}, + "up": {"uv": [8, 8, 7.875, 7.875], "texture": "#1"}, + "down": {"uv": [8.125, 0, 8, 0.125], "texture": "#1"} + } + }, + { + "from": [0, 2, 15], + "to": [1, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 15]}, + "faces": { + "north": {"uv": [6.5, 6.75, 6.625, 10.25], "texture": "#1"}, + "east": {"uv": [6.625, 6.75, 6.75, 10.25], "texture": "#1"}, + "south": {"uv": [6.75, 6.75, 6.875, 10.25], "texture": "#1"}, + "west": {"uv": [6.875, 6.75, 7, 10.25], "texture": "#1"}, + "up": {"uv": [8.125, 0.25, 8, 0.125], "texture": "#1"}, + "down": {"uv": [8.125, 0.25, 8, 0.375], "texture": "#1"} + } + }, + { + "from": [15, 2, 15], + "to": [16, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 15]}, + "faces": { + "north": {"uv": [7, 6.75, 7.125, 10.25], "texture": "#1"}, + "east": {"uv": [7.125, 6.75, 7.25, 10.25], "texture": "#1"}, + "south": {"uv": [0, 7.25, 0.125, 10.75], "texture": "#1"}, + "west": {"uv": [0.125, 7.25, 0.25, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.5, 8, 0.375], "texture": "#1"}, + "down": {"uv": [8.125, 0.5, 8, 0.625], "texture": "#1"} + } + }, + { + "from": [15, 2, 0], + "to": [16, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 0]}, + "faces": { + "north": {"uv": [0.25, 7.25, 0.375, 10.75], "texture": "#1"}, + "east": {"uv": [0.375, 7.25, 0.5, 10.75], "texture": "#1"}, + "south": {"uv": [0.5, 7.25, 0.625, 10.75], "texture": "#1"}, + "west": {"uv": [0.625, 7.25, 0.75, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.75, 8, 0.625], "texture": "#1"}, + "down": {"uv": [0.875, 8, 0.75, 8.125], "texture": "#1"} + } + }, + { + "from": [0.15, 1.65, 0.15], + "to": [15.85, 30.35, 15.85], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 1.5, 0]}, + "faces": { + "north": {"uv": [0, 0, 2, 3.625], "texture": "#1"}, + "east": {"uv": [2, 0, 4, 3.625], "texture": "#1"}, + "south": {"uv": [0, 3.625, 2, 7.25], "texture": "#1"}, + "west": {"uv": [2, 3.625, 4, 7.25], "texture": "#1"}, + "up": {"uv": [6, 6, 4, 4], "texture": "#1"}, + "down": {"uv": [8, 0, 6, 2], "texture": "#1"} + } + }, + { + "from": [0, 30, 0], + "to": [16, 32, 16], + "faces": { + "north": {"uv": [6, 6.5, 8, 6.75], "texture": "#1"}, + "east": {"uv": [6.75, 4, 8.75, 4.25], "texture": "#1"}, + "south": {"uv": [6.75, 4.25, 8.75, 4.5], "texture": "#1"}, + "west": {"uv": [6.75, 4.5, 8.75, 4.75], "texture": "#1"}, + "up": {"uv": [8, 4, 6, 2], "texture": "#1"}, + "down": {"uv": [6, 6, 4, 8], "texture": "#1"} + } + }, + { + "from": [5, 28, 5], + "to": [11, 30, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -2, 0]}, + "faces": { + "north": {"uv": [1.5, 7.25, 2.25, 7.5], "texture": "#1"}, + "east": {"uv": [2.25, 7.25, 3, 7.5], "texture": "#1"}, + "south": {"uv": [3, 7.25, 3.75, 7.5], "texture": "#1"}, + "west": {"uv": [7.25, 6.75, 8, 7], "texture": "#1"}, + "up": {"uv": [6.75, 4.75, 6, 4], "texture": "#1"}, + "down": {"uv": [6.75, 4.75, 6, 5.5], "texture": "#1"} + } + }, + { + "from": [7.5, 22, 7.5], + "to": [8.5, 28, 8.5], + "rotation": {"angle": 0, "axis": "y", "origin": [0.5, -4, -0.5]}, + "faces": { + "north": {"uv": [7.5, 7.75, 7.625, 8.5], "texture": "#1"}, + "east": {"uv": [7.625, 7.75, 7.75, 8.5], "texture": "#1"}, + "south": {"uv": [7.75, 7.75, 7.875, 8.5], "texture": "#1"}, + "west": {"uv": [2, 7.875, 2.125, 8.625], "texture": "#1"}, + "up": {"uv": [8.125, 0.875, 8, 0.75], "texture": "#1"}, + "down": {"uv": [1, 8, 0.875, 8.125], "texture": "#1"} + } + }, + { + "from": [6, 17, 6.6], + "to": [9, 23, 9.6], + "rotation": {"angle": 45, "axis": "z", "origin": [7, 21, 6.6]}, + "faces": { + "north": {"uv": [6.75, 4.75, 7.125, 5.5], "texture": "#1"}, + "east": {"uv": [7.125, 4.75, 7.5, 5.5], "texture": "#1"}, + "south": {"uv": [0.75, 7.25, 1.125, 8], "texture": "#1"}, + "west": {"uv": [1.125, 7.25, 1.5, 8], "texture": "#1"}, + "up": {"uv": [2.375, 7.875, 2, 7.5], "texture": "#1"}, + "down": {"uv": [2.75, 7.5, 2.375, 7.875], "texture": "#1"} + } + }, + { + "from": [6.8, 18.8, 6.3], + "to": [7.8, 20.8, 7.3], + "rotation": {"angle": -22.5, "axis": "z", "origin": [6.8, 20.8, 6.3]}, + "faces": { + "north": {"uv": [3.75, 7.875, 4, 8], "rotation": 90, "texture": "#1"}, + "east": {"uv": [8.125, 5, 7.875, 5.125], "rotation": 270, "texture": "#1"}, + "south": {"uv": [7.875, 4.75, 8.125, 4.875], "rotation": 270, "texture": "#1"}, + "west": {"uv": [8.125, 5, 7.875, 4.875], "rotation": 270, "texture": "#1"}, + "up": {"uv": [8, 0.875, 8.125, 1], "rotation": 270, "texture": "#1"}, + "down": {"uv": [1, 8, 1.125, 8.125], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [5, 20, 8.7], + "to": [7, 21, 9.7], + "rotation": {"angle": 45, "axis": "z", "origin": [7, 21, 9.7]}, + "faces": { + "north": {"uv": [7.875, 5.125, 8.125, 5.25], "texture": "#1"}, + "east": {"uv": [8, 1, 8.125, 1.125], "texture": "#1"}, + "south": {"uv": [7.875, 5.25, 8.125, 5.375], "texture": "#1"}, + "west": {"uv": [1.125, 8, 1.25, 8.125], "texture": "#1"}, + "up": {"uv": [8.125, 5.5, 7.875, 5.375], "texture": "#1"}, + "down": {"uv": [8.125, 7, 7.875, 7.125], "texture": "#1"} + } + }, + { + "from": [3.75, 21.15, 6.55], + "to": [6.85, 24.25, 9.65], + "rotation": {"angle": -22.5, "axis": "z", "origin": [5.8, 22.2, 6.6]}, + "faces": { + "north": {"uv": [2.75, 7.5, 3.125, 7.875], "rotation": 90, "texture": "#1"}, + "east": {"uv": [7.875, 7.375, 7.5, 7.75], "rotation": 270, "texture": "#1"}, + "south": {"uv": [7.5, 4.75, 7.875, 5.125], "rotation": 270, "texture": "#1"}, + "west": {"uv": [7.875, 7.375, 7.5, 7], "rotation": 270, "texture": "#1"}, + "up": {"uv": [3.125, 7.5, 3.5, 7.875], "rotation": 270, "texture": "#1"}, + "down": {"uv": [7.5, 5.125, 7.875, 5.5], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [2.6, 21.7, 7.6], + "to": [4.6, 23.7, 8.6], + "rotation": {"angle": 0, "axis": "y", "origin": [5.6, 22.7, 6.6]}, + "faces": { + "north": {"uv": [2.125, 7.875, 2.375, 8.125], "rotation": 90, "texture": "#1"}, + "east": {"uv": [8.125, 7.5, 7.875, 7.625], "rotation": 270, "texture": "#1"}, + "south": {"uv": [2.375, 7.875, 2.625, 8.125], "rotation": 270, "texture": "#1"}, + "west": {"uv": [8.125, 7.5, 7.875, 7.375], "rotation": 270, "texture": "#1"}, + "up": {"uv": [3.375, 7.875, 3.5, 8.125], "rotation": 270, "texture": "#1"}, + "down": {"uv": [7.875, 7.125, 8, 7.375], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [8.475, 14.7, 7.1], + "to": [10.475, 19.7, 9.1], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8.475, 17.7, 7.1]}, + "faces": { + "north": {"uv": [3.75, 7.25, 4, 7.875], "texture": "#1"}, + "east": {"uv": [7.25, 7, 7.5, 7.625], "texture": "#1"}, + "south": {"uv": [1.5, 7.5, 1.75, 8.125], "texture": "#1"}, + "west": {"uv": [1.75, 7.5, 2, 8.125], "texture": "#1"}, + "up": {"uv": [2.875, 8.125, 2.625, 7.875], "texture": "#1"}, + "down": {"uv": [3.125, 7.875, 2.875, 8.125], "texture": "#1"} + } + }, + { + "from": [5.975, 14.5, 7.6], + "to": [9.975, 16.5, 8.6], + "rotation": {"angle": -22.5, "axis": "z", "origin": [7.975, 16.5, 6.6]}, + "faces": { + "north": {"uv": [3.5, 7.5, 3.75, 8], "rotation": 270, "texture": "#1"}, + "east": {"uv": [8.125, 7.75, 7.875, 7.625], "rotation": 90, "texture": "#1"}, + "south": {"uv": [7.25, 7.625, 7.5, 8.125], "rotation": 90, "texture": "#1"}, + "west": {"uv": [8.125, 7.75, 7.875, 7.875], "rotation": 90, "texture": "#1"}, + "up": {"uv": [3.25, 7.875, 3.375, 8.375], "rotation": 90, "texture": "#1"}, + "down": {"uv": [3.125, 7.875, 3.25, 8.375], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [5.975, 16.5, 7.6], + "to": [6.975, 17.5, 8.6], + "rotation": {"angle": -22.5, "axis": "z", "origin": [7.975, 16.5, 6.6]}, + "faces": { + "north": {"uv": [8, 1.125, 8.125, 1.25], "rotation": 270, "texture": "#1"}, + "east": {"uv": [8.125, 1.5, 8, 1.375], "rotation": 90, "texture": "#1"}, + "south": {"uv": [8, 1.25, 8.125, 1.375], "rotation": 90, "texture": "#1"}, + "west": {"uv": [8.125, 1.5, 8, 1.625], "rotation": 90, "texture": "#1"}, + "up": {"uv": [1.375, 8, 1.5, 8.125], "rotation": 90, "texture": "#1"}, + "down": {"uv": [1.25, 8, 1.375, 8.125], "rotation": 90, "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_lefthand": { + "rotation": [0, -135, 0], + "scale": [0.2, 0.2, 0.2] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, -135, 0], + "translation": [0, -3, 0], + "scale": [0.4, 0.4, 0.4] + }, + "head": { + "translation": [0, 10, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "translation": [0, -4, 0], + "scale": [0.5, 0.5, 0.5] + } + }, + "groups": [ + { + "name": "group", + "origin": [8, 8, 8], + "scope": 0, + "color": 0, + "children": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + { + "name": "group", + "origin": [8, 8, 8], + "scope": 0, + "color": 0, + "children": [9, 10, 11, 12, 13, 14, 15, 16] + } + ] + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator.json b/common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator.json new file mode 100644 index 0000000..f4ecac7 --- /dev/null +++ b/common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator.json @@ -0,0 +1,174 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "ambientocclusion": false, + "render_type": "cutout", + "texture_size": [128, 128], + "textures": { + "1": "jurassicrevived:block/white_cultivator", + "particle": "jurassicrevived:block/white_cultivator" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [6, 5.5, 8, 5.75], "texture": "#1"}, + "east": {"uv": [6, 5.75, 8, 6], "texture": "#1"}, + "south": {"uv": [6, 6, 8, 6.25], "texture": "#1"}, + "west": {"uv": [6, 6.25, 8, 6.5], "texture": "#1"}, + "up": {"uv": [6, 2, 4, 0], "texture": "#1"}, + "down": {"uv": [6, 2, 4, 4], "texture": "#1"} + } + }, + { + "from": [0, 2, 0], + "to": [1, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 0]}, + "faces": { + "north": {"uv": [6, 6.75, 6.125, 10.25], "texture": "#1"}, + "east": {"uv": [6.125, 6.75, 6.25, 10.25], "texture": "#1"}, + "south": {"uv": [6.25, 6.75, 6.375, 10.25], "texture": "#1"}, + "west": {"uv": [6.375, 6.75, 6.5, 10.25], "texture": "#1"}, + "up": {"uv": [8, 8, 7.875, 7.875], "texture": "#1"}, + "down": {"uv": [8.125, 0, 8, 0.125], "texture": "#1"} + } + }, + { + "from": [0, 2, 15], + "to": [1, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 15]}, + "faces": { + "north": {"uv": [6.5, 6.75, 6.625, 10.25], "texture": "#1"}, + "east": {"uv": [6.625, 6.75, 6.75, 10.25], "texture": "#1"}, + "south": {"uv": [6.75, 6.75, 6.875, 10.25], "texture": "#1"}, + "west": {"uv": [6.875, 6.75, 7, 10.25], "texture": "#1"}, + "up": {"uv": [8.125, 0.25, 8, 0.125], "texture": "#1"}, + "down": {"uv": [8.125, 0.25, 8, 0.375], "texture": "#1"} + } + }, + { + "from": [15, 2, 15], + "to": [16, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 15]}, + "faces": { + "north": {"uv": [7, 6.75, 7.125, 10.25], "texture": "#1"}, + "east": {"uv": [7.125, 6.75, 7.25, 10.25], "texture": "#1"}, + "south": {"uv": [0, 7.25, 0.125, 10.75], "texture": "#1"}, + "west": {"uv": [0.125, 7.25, 0.25, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.5, 8, 0.375], "texture": "#1"}, + "down": {"uv": [8.125, 0.5, 8, 0.625], "texture": "#1"} + } + }, + { + "from": [15, 2, 0], + "to": [16, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 0]}, + "faces": { + "north": {"uv": [0.25, 7.25, 0.375, 10.75], "texture": "#1"}, + "east": {"uv": [0.375, 7.25, 0.5, 10.75], "texture": "#1"}, + "south": {"uv": [0.5, 7.25, 0.625, 10.75], "texture": "#1"}, + "west": {"uv": [0.625, 7.25, 0.75, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.75, 8, 0.625], "texture": "#1"}, + "down": {"uv": [0.875, 8, 0.75, 8.125], "texture": "#1"} + } + }, + { + "from": [0.15, 1.65, 0.15], + "to": [15.85, 30.35, 15.85], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 1.5, 0]}, + "faces": { + "north": {"uv": [0, 0, 2, 3.625], "texture": "#1"}, + "east": {"uv": [2, 0, 4, 3.625], "texture": "#1"}, + "south": {"uv": [0, 3.625, 2, 7.25], "texture": "#1"}, + "west": {"uv": [2, 3.625, 4, 7.25], "texture": "#1"}, + "up": {"uv": [6, 6, 4, 4], "texture": "#1"}, + "down": {"uv": [8, 0, 6, 2], "texture": "#1"} + } + }, + { + "from": [0, 30, 0], + "to": [16, 32, 16], + "faces": { + "north": {"uv": [6, 6.5, 8, 6.75], "texture": "#1"}, + "east": {"uv": [6.75, 4, 8.75, 4.25], "texture": "#1"}, + "south": {"uv": [6.75, 4.25, 8.75, 4.5], "texture": "#1"}, + "west": {"uv": [6.75, 4.5, 8.75, 4.75], "texture": "#1"}, + "up": {"uv": [8, 4, 6, 2], "texture": "#1"}, + "down": {"uv": [6, 6, 4, 8], "texture": "#1"} + } + }, + { + "from": [5, 28, 5], + "to": [11, 30, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -2, 0]}, + "faces": { + "north": {"uv": [1.5, 7.25, 2.25, 7.5], "texture": "#1"}, + "east": {"uv": [2.25, 7.25, 3, 7.5], "texture": "#1"}, + "south": {"uv": [3, 7.25, 3.75, 7.5], "texture": "#1"}, + "west": {"uv": [7.25, 6.75, 8, 7], "texture": "#1"}, + "up": {"uv": [6.75, 4.75, 6, 4], "texture": "#1"}, + "down": {"uv": [6.75, 4.75, 6, 5.5], "texture": "#1"} + } + }, + { + "from": [7.5, 22, 7.5], + "to": [8.5, 28, 8.5], + "rotation": {"angle": 0, "axis": "y", "origin": [0.5, -4, -0.5]}, + "faces": { + "north": {"uv": [7.5, 7.75, 7.625, 8.5], "texture": "#1"}, + "east": {"uv": [7.625, 7.75, 7.75, 8.5], "texture": "#1"}, + "south": {"uv": [7.75, 7.75, 7.875, 8.5], "texture": "#1"}, + "west": {"uv": [2, 7.875, 2.125, 8.625], "texture": "#1"}, + "up": {"uv": [8.125, 0.875, 8, 0.75], "texture": "#1"}, + "down": {"uv": [1, 8, 0.875, 8.125], "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_lefthand": { + "rotation": [0, -135, 0], + "scale": [0.2, 0.2, 0.2] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, -135, 0], + "translation": [0, -3, 0], + "scale": [0.4, 0.4, 0.4] + }, + "head": { + "translation": [0, 10, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "translation": [0, -4, 0], + "scale": [0.5, 0.5, 0.5] + } + }, + "groups": [ + { + "name": "group", + "origin": [8, 8, 8], + "scope": 0, + "color": 0, + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8] + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator_lit.json b/common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator_lit.json new file mode 100644 index 0000000..61d2b58 --- /dev/null +++ b/common/src/main/resources/assets/jurassicrevived/models/block/white_cultivator_lit.json @@ -0,0 +1,295 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "ambientocclusion": false, + "render_type": "cutout", + "texture_size": [128, 128], + "textures": { + "1": "jurassicrevived:block/white_cultivator_lit", + "particle": "jurassicrevived:block/white_cultivator_lit" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [6, 5.5, 8, 5.75], "texture": "#1"}, + "east": {"uv": [6, 5.75, 8, 6], "texture": "#1"}, + "south": {"uv": [6, 6, 8, 6.25], "texture": "#1"}, + "west": {"uv": [6, 6.25, 8, 6.5], "texture": "#1"}, + "up": {"uv": [6, 2, 4, 0], "texture": "#1"}, + "down": {"uv": [6, 2, 4, 4], "texture": "#1"} + } + }, + { + "from": [0, 2, 0], + "to": [1, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 0]}, + "faces": { + "north": {"uv": [6, 6.75, 6.125, 10.25], "texture": "#1"}, + "east": {"uv": [6.125, 6.75, 6.25, 10.25], "texture": "#1"}, + "south": {"uv": [6.25, 6.75, 6.375, 10.25], "texture": "#1"}, + "west": {"uv": [6.375, 6.75, 6.5, 10.25], "texture": "#1"}, + "up": {"uv": [8, 8, 7.875, 7.875], "texture": "#1"}, + "down": {"uv": [8.125, 0, 8, 0.125], "texture": "#1"} + } + }, + { + "from": [0, 2, 15], + "to": [1, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 2, 15]}, + "faces": { + "north": {"uv": [6.5, 6.75, 6.625, 10.25], "texture": "#1"}, + "east": {"uv": [6.625, 6.75, 6.75, 10.25], "texture": "#1"}, + "south": {"uv": [6.75, 6.75, 6.875, 10.25], "texture": "#1"}, + "west": {"uv": [6.875, 6.75, 7, 10.25], "texture": "#1"}, + "up": {"uv": [8.125, 0.25, 8, 0.125], "texture": "#1"}, + "down": {"uv": [8.125, 0.25, 8, 0.375], "texture": "#1"} + } + }, + { + "from": [15, 2, 15], + "to": [16, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 15]}, + "faces": { + "north": {"uv": [7, 6.75, 7.125, 10.25], "texture": "#1"}, + "east": {"uv": [7.125, 6.75, 7.25, 10.25], "texture": "#1"}, + "south": {"uv": [0, 7.25, 0.125, 10.75], "texture": "#1"}, + "west": {"uv": [0.125, 7.25, 0.25, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.5, 8, 0.375], "texture": "#1"}, + "down": {"uv": [8.125, 0.5, 8, 0.625], "texture": "#1"} + } + }, + { + "from": [15, 2, 0], + "to": [16, 30, 1], + "rotation": {"angle": 0, "axis": "y", "origin": [16, 2, 0]}, + "faces": { + "north": {"uv": [0.25, 7.25, 0.375, 10.75], "texture": "#1"}, + "east": {"uv": [0.375, 7.25, 0.5, 10.75], "texture": "#1"}, + "south": {"uv": [0.5, 7.25, 0.625, 10.75], "texture": "#1"}, + "west": {"uv": [0.625, 7.25, 0.75, 10.75], "texture": "#1"}, + "up": {"uv": [8.125, 0.75, 8, 0.625], "texture": "#1"}, + "down": {"uv": [0.875, 8, 0.75, 8.125], "texture": "#1"} + } + }, + { + "from": [0.15, 1.65, 0.15], + "to": [15.85, 30.35, 15.85], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 1.5, 0]}, + "faces": { + "north": {"uv": [0, 0, 2, 3.625], "texture": "#1"}, + "east": {"uv": [2, 0, 4, 3.625], "texture": "#1"}, + "south": {"uv": [0, 3.625, 2, 7.25], "texture": "#1"}, + "west": {"uv": [2, 3.625, 4, 7.25], "texture": "#1"}, + "up": {"uv": [6, 6, 4, 4], "texture": "#1"}, + "down": {"uv": [8, 0, 6, 2], "texture": "#1"} + } + }, + { + "from": [0, 30, 0], + "to": [16, 32, 16], + "faces": { + "north": {"uv": [6, 6.5, 8, 6.75], "texture": "#1"}, + "east": {"uv": [6.75, 4, 8.75, 4.25], "texture": "#1"}, + "south": {"uv": [6.75, 4.25, 8.75, 4.5], "texture": "#1"}, + "west": {"uv": [6.75, 4.5, 8.75, 4.75], "texture": "#1"}, + "up": {"uv": [8, 4, 6, 2], "texture": "#1"}, + "down": {"uv": [6, 6, 4, 8], "texture": "#1"} + } + }, + { + "from": [5, 28, 5], + "to": [11, 30, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -2, 0]}, + "faces": { + "north": {"uv": [1.5, 7.25, 2.25, 7.5], "texture": "#1"}, + "east": {"uv": [2.25, 7.25, 3, 7.5], "texture": "#1"}, + "south": {"uv": [3, 7.25, 3.75, 7.5], "texture": "#1"}, + "west": {"uv": [7.25, 6.75, 8, 7], "texture": "#1"}, + "up": {"uv": [6.75, 4.75, 6, 4], "texture": "#1"}, + "down": {"uv": [6.75, 4.75, 6, 5.5], "texture": "#1"} + } + }, + { + "from": [7.5, 22, 7.5], + "to": [8.5, 28, 8.5], + "rotation": {"angle": 0, "axis": "y", "origin": [0.5, -4, -0.5]}, + "faces": { + "north": {"uv": [7.5, 7.75, 7.625, 8.5], "texture": "#1"}, + "east": {"uv": [7.625, 7.75, 7.75, 8.5], "texture": "#1"}, + "south": {"uv": [7.75, 7.75, 7.875, 8.5], "texture": "#1"}, + "west": {"uv": [2, 7.875, 2.125, 8.625], "texture": "#1"}, + "up": {"uv": [8.125, 0.875, 8, 0.75], "texture": "#1"}, + "down": {"uv": [1, 8, 0.875, 8.125], "texture": "#1"} + } + }, + { + "from": [6, 17, 6.6], + "to": [9, 23, 9.6], + "rotation": {"angle": 45, "axis": "z", "origin": [7, 21, 6.6]}, + "faces": { + "north": {"uv": [6.75, 4.75, 7.125, 5.5], "texture": "#1"}, + "east": {"uv": [7.125, 4.75, 7.5, 5.5], "texture": "#1"}, + "south": {"uv": [0.75, 7.25, 1.125, 8], "texture": "#1"}, + "west": {"uv": [1.125, 7.25, 1.5, 8], "texture": "#1"}, + "up": {"uv": [2.375, 7.875, 2, 7.5], "texture": "#1"}, + "down": {"uv": [2.75, 7.5, 2.375, 7.875], "texture": "#1"} + } + }, + { + "from": [4.8, 19.8, 6.3], + "to": [6.8, 20.8, 7.3], + "rotation": {"angle": 67.5, "axis": "z", "origin": [6.8, 20.8, 6.3]}, + "faces": { + "north": {"uv": [3.75, 7.875, 4, 8], "texture": "#1"}, + "east": {"uv": [8, 0.875, 8.125, 1], "texture": "#1"}, + "south": {"uv": [7.875, 4.75, 8.125, 4.875], "texture": "#1"}, + "west": {"uv": [1, 8, 1.125, 8.125], "texture": "#1"}, + "up": {"uv": [8.125, 5, 7.875, 4.875], "texture": "#1"}, + "down": {"uv": [8.125, 5, 7.875, 5.125], "texture": "#1"} + } + }, + { + "from": [5, 20, 8.7], + "to": [7, 21, 9.7], + "rotation": {"angle": 45, "axis": "z", "origin": [7, 21, 9.7]}, + "faces": { + "north": {"uv": [7.875, 5.125, 8.125, 5.25], "texture": "#1"}, + "east": {"uv": [8, 1, 8.125, 1.125], "texture": "#1"}, + "south": {"uv": [7.875, 5.25, 8.125, 5.375], "texture": "#1"}, + "west": {"uv": [1.125, 8, 1.25, 8.125], "texture": "#1"}, + "up": {"uv": [8.125, 5.5, 7.875, 5.375], "texture": "#1"}, + "down": {"uv": [8.125, 7, 7.875, 7.125], "texture": "#1"} + } + }, + { + "from": [4.75, 21.15, 6.55], + "to": [7.85, 24.25, 9.65], + "rotation": {"angle": 67.5, "axis": "z", "origin": [5.8, 22.2, 6.6]}, + "faces": { + "north": {"uv": [2.75, 7.5, 3.125, 7.875], "texture": "#1"}, + "east": {"uv": [3.125, 7.5, 3.5, 7.875], "texture": "#1"}, + "south": {"uv": [7.5, 4.75, 7.875, 5.125], "texture": "#1"}, + "west": {"uv": [7.5, 5.125, 7.875, 5.5], "texture": "#1"}, + "up": {"uv": [7.875, 7.375, 7.5, 7], "texture": "#1"}, + "down": {"uv": [7.875, 7.375, 7.5, 7.75], "texture": "#1"} + } + }, + { + "from": [4.6, 23.4, 7.6], + "to": [6.6, 25.4, 8.6], + "rotation": {"angle": 67.5, "axis": "z", "origin": [5.6, 22.4, 6.6]}, + "faces": { + "north": {"uv": [2.125, 7.875, 2.375, 8.125], "texture": "#1"}, + "east": {"uv": [3.375, 7.875, 3.5, 8.125], "texture": "#1"}, + "south": {"uv": [2.375, 7.875, 2.625, 8.125], "texture": "#1"}, + "west": {"uv": [7.875, 7.125, 8, 7.375], "texture": "#1"}, + "up": {"uv": [8.125, 7.5, 7.875, 7.375], "texture": "#1"}, + "down": {"uv": [8.125, 7.5, 7.875, 7.625], "texture": "#1"} + } + }, + { + "from": [8.475, 14.7, 7.1], + "to": [10.475, 19.7, 9.1], + "rotation": {"angle": -22.5, "axis": "z", "origin": [8.475, 17.7, 7.1]}, + "faces": { + "north": {"uv": [3.75, 7.25, 4, 7.875], "texture": "#1"}, + "east": {"uv": [7.25, 7, 7.5, 7.625], "texture": "#1"}, + "south": {"uv": [1.5, 7.5, 1.75, 8.125], "texture": "#1"}, + "west": {"uv": [1.75, 7.5, 2, 8.125], "texture": "#1"}, + "up": {"uv": [2.875, 8.125, 2.625, 7.875], "texture": "#1"}, + "down": {"uv": [3.125, 7.875, 2.875, 8.125], "texture": "#1"} + } + }, + { + "from": [5.975, 14.5, 7.6], + "to": [9.975, 16.5, 8.6], + "rotation": {"angle": -22.5, "axis": "z", "origin": [7.975, 16.5, 6.6]}, + "faces": { + "north": {"uv": [3.5, 7.5, 3.75, 8], "rotation": 270, "texture": "#1"}, + "east": {"uv": [8.125, 7.75, 7.875, 7.625], "rotation": 90, "texture": "#1"}, + "south": {"uv": [7.25, 7.625, 7.5, 8.125], "rotation": 90, "texture": "#1"}, + "west": {"uv": [8.125, 7.75, 7.875, 7.875], "rotation": 90, "texture": "#1"}, + "up": {"uv": [3.25, 7.875, 3.375, 8.375], "rotation": 90, "texture": "#1"}, + "down": {"uv": [3.125, 7.875, 3.25, 8.375], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6.975, 14.5, 7.6], + "to": [7.975, 15.5, 8.6], + "rotation": {"angle": -112.5, "axis": "z", "origin": [7.975, 16.5, 6.6]}, + "faces": { + "north": {"uv": [8, 1.125, 8.125, 1.25], "texture": "#1"}, + "east": {"uv": [1.25, 8, 1.375, 8.125], "texture": "#1"}, + "south": {"uv": [8, 1.25, 8.125, 1.375], "texture": "#1"}, + "west": {"uv": [1.375, 8, 1.5, 8.125], "texture": "#1"}, + "up": {"uv": [8.125, 1.5, 8, 1.375], "texture": "#1"}, + "down": {"uv": [8.125, 1.5, 8, 1.625], "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.2, 0.2, 0.2] + }, + "firstperson_lefthand": { + "rotation": [0, -135, 0], + "scale": [0.2, 0.2, 0.2] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, -135, 0], + "translation": [0, -3, 0], + "scale": [0.4, 0.4, 0.4] + }, + "head": { + "translation": [0, 10, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "translation": [0, -4, 0], + "scale": [0.5, 0.5, 0.5] + } + }, + "groups": [ + { + "name": "group", + "origin": [8, 8, 8], + "scope": 0, + "color": 0, + "children": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + { + "name": "group", + "origin": [8, 8, 8], + "scope": 0, + "color": 0, + "children": [9, 10, 11, 12, 13, 14, 15, 16] + } + ] + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/alligator_gar_egg.png b/common/src/main/resources/assets/jurassicrevived/textures/block/alligator_gar_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..24676ea389b263dd241d7a22d201b20cc428faa1 GIT binary patch literal 343 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 B?!Ev3 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator_lit.png b/common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator_lit.png new file mode 100644 index 0000000000000000000000000000000000000000..23444cea8a64432683a7efc6765645bd9a56af5e GIT binary patch literal 3576 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 B?!Ev3 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/entity/compsognathus_rebirth.png b/common/src/main/resources/assets/jurassicrevived/textures/entity/compsognathus_rebirth.png new file mode 100644 index 0000000000000000000000000000000000000000..7ecfad3e933aab515170ae36358cfd8925c21d13 GIT binary patch literal 13871 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 Z;1@H8V>8+|+hG6z002ovPDHLkV1k4?|Jwin literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_syringe.png b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_syringe.png new file mode 100644 index 0000000000000000000000000000000000000000..cc69814a296de8643a6189c9f13b52645f702d0f GIT binary patch literal 526 zcmV+p0`dKcP)4# zP#_kw`A-8@;&IAkGGZ_opxf=T){0L7QmGW3aeIA9 zw>MX$>pB&SMGMA+cLB*{l6Eu|Fz(G>f|fo&Hk)lLlwz(CZGfy^5@oyxL&(LTzUWmEZao}>f;Pd&&@AuP2Gzf8bXYLCu zrjPJ^X0teSJAh`hDGb9vzu$*=w7s-@f>x{b>d7`mQdQNlF3U1T-EPckY0T?;V5r^r zR+g&OstAX}#NqLHAe#Ul=lQpOO}x1oB@SzZN~IzsNrDgp?RHyuy0>rxU(TF z+D^x4?dRad0z-EmYk9u(O{7=fAT13BbZ~xhx`)h(+f$ zH|T5I_&+v^)zxDwM`P=_I6uVHxPm_;ga-fs0RR7*$3@iu000I_L_t&o0Ao94%P)B9;1nE;*L=mEbksu-{Hfmwx1LO$;X_7W|9w1HH zKmrMbbQ^vPbL?Gmmm&wl?9P7QZ)TTUlNG;(fOhTIH2+=cMruH=AAdad+QiKkKw-<@3q}Tr zfolNa91vjEZiD~|LBKkl&DpomcL2PwmL-`?rvD=~OZR!Tm#34l3^*=D-jT8*9PeAcQEWuqXr%Tr7+!L{TFc>`WsX)1;I%+5~LWM)5$gGJ=I@ zCqb~V6ftVtC7KO6jHBO%T~>3r;K0ky&dl?Ca~Sc@rdzPMcEmW2lcTMvTR>3zPypF% z7H+qj(LY6(V0A0buJ)oh+l-*g8zfH6pMv$>bJpy%!xsptkXBMx5IeYFjn)PgdfQ zI~HV|cY)m}Q)L0!ltfP-t6td1bcpf(FteJ?XtG=2u$7-zJ_1!EkP?|2thg|KYMGfV z7Ig3)*qjdJJ{U5&BB;p%>JUhwzBaz`ATvtu$fX4w$F}kGkc3nys7q9VI`XR{iUI`T z6`52DMe+GNFDOZGz-LKb`2_#~|Nm)-qVWI#00v1!K~w_(r{0?OKDlR600000NkvXX Hu0mjf%A&_# literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_skull_fossil.png b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_skull_fossil.png new file mode 100644 index 0000000000000000000000000000000000000000..e372b3025a9d90ecf7fa9be7fdf883474894d1b3 GIT binary patch literal 812 zcmV+{1JnG8P)VGd000McNliru-~j~{5Gq@`(!2lw0=Y>< zK~z}7)mO`E+dvdOBP*^G(-ztnGvJW!?JM`Iv|jB=gvLn%)NKUgmaGP90s0wBmjiIOP(A7 z=X~WS@Eo!!pS8DOnOdRm8p?Y`RXgEZ7JcA3M&LP>9D6)%$AF7TY!f#_&!9HSnCBGUQg;&%kruY&t(kQ6C6>*QAy`6Yo3JvVQ?UtJz37jm8s_v&I$xLM?lm zWjBiwNd|8<8(aoxH5>f;>LN8)1*L(RWf3X_ptCIsesg;tze}40Ga63_wQMfdtO3{p z5QV-Qe>ZZNr=)H*8~mufUs#$t7;UR&08-mzl<9tw`C$ZqXH5Q!Rqq-4D9zbwG}dWQInG8mz#tFnMp1CkDiRDC&vJQPPc~- z@888fA3uFg1XFF&t^lY|%bu(D!d9#X?{s@95K$E6`gXd#R33!BYf#Hxlm?&zkswqx z@`9F4z)S$4@4lp#9f|FzsOLde@O6R~mLaulscQv59l$qraV^Q_qw&Q2r*}eexu})3zRbea{vnfJkNO(BUV5#GqcWY0Y*y56)B~(L^c>nMsGN!%WxAzkRd|7#gha0 qul}5x8<3lbbxeg2p_culjQ?Mc#ZQB*8b`7K0000k)w zbti4zb``-^eqgOKxQ=h<9n#%pskS=IbLN~g=lPxYo%1UAk5;eO>7M~?4g>~>t!(pZmYz|h6!#rsO+Azf6r=)!uEKJNFRRI61H3WbQ}a=GA;08Z!lU9k4w;A^{aYm1cecj%)5UKL*A^QV1`WjXUc))K&z za=9$R;jnos&soFa0E0mv2fZE+hhL<=!We%8<_3Sp4*&oF|Nls?0~-JU00v1!K~w_( X=seFGPTw3L00000NkvXXu0mjfZvzU4 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_tissue.png b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_tissue.png new file mode 100644 index 0000000000000000000000000000000000000000..028290f47a2eeea100c6a7610a5c0d9e99529dbd GIT binary patch literal 470 zcmV;{0V)28P)vrNI`r^(&OPV+zH{#FlYf4H0`Ai1>h|JL;d}Ah0Ej-Vyx8TE;5m1L zIDm(nw9-v;@qJ@qFJ(+bW(5x)hsRqh z14O_zfKUennAmL|fQHaO92f~XZ=v4-Fg3Te02K991iXcYkVn*Y0~!#FPEL#Y{3IGO zHZ>#Uxe7z*(^f26s*j#l%Yr#3H6dIv;$~nGMf-9-(OFF zWtn1{A5tk4q;9=8Eia8~N#wiX5Pkpv0RR7f&Q>P?000I_L_t&o0E+F__7(t3asU7T M07*qoM6N<$f*y>^b^rhX literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_alligator_gar_skull.png b/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_alligator_gar_skull.png new file mode 100644 index 0000000000000000000000000000000000000000..722a44fb619a210c7181bdb519e7eab99f5299cf GIT binary patch literal 607 zcmV-l0-*hgP)VGd000McNliru-~k2<5fdEdT;u=%0qjXc zK~z}7?U%n#!ax+qzh@Xob%1}wO--CkOc~u685kTf#i@f#Ixs=fjtmSWENm_&Bo2&f zSo{NAVZ%g4w&x&syt`ic5sEl)$t7*Cm-l(!@4Mbr5D~W7_ORu)1K2u1DsCVw=OWcv zs&~c40c7CPZ8a7uQ4k_hJ@8zjkN&I=d;0yf2cAoO-a1{#??712QOUo-)5|MP&Q5j8 zuTNnAKv$#UCt`~rA}u(8D8L+;bwNbnxwFiV4x$Kw_tls@j_HW|Vkgztz7TBZ| zcpr_>X*E@F*^bXI@cekMt0Ds}vdK`4ClQu&RH}D{whZ%yA^;$h&8kUh$APSqMo^1n zrG2oLELg5cic2Cr;~9h)w^P#7h5H0K5N!9l*Z__yMU*lun!8x6S|n002ovPDHLkV1f|m1n>X= literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_coelacanth_skull.png b/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_coelacanth_skull.png new file mode 100644 index 0000000000000000000000000000000000000000..e2d2bf068b922d6ce297531c1a33d4f08d81a215 GIT binary patch literal 488 zcmVP)VGd000McNliru-~k2LO>9T*tdI!3BQ7bGh6 zKf0w-A?kJ=B2ya*7^hVhTRI7Iw(p(qe71&&aLzV@GdBgG02IK5%p~HNjpAW#ciO)J z5XVGnfH)>vUeF0O2nG>5CA1CXzCYhM32md2`oF%l5wSZ5Sg(j<;&?Xi-l>iI6A~}@ zHB?ebNVi>|P9RUS&aru#9gS~XA&60*_m&qxBj#nnc}m-OHV1t=Y5bQ?Ld#trja^V_Y@a(7v@ekP ztn}7_#d5`a<*woDaA<^r1U^{Xoi?;cX?-suy5M5D0sw#{j^Ot0zS2L258QZGNA=PG ztnnm{8W11*ee2vLj)d|+6L}L7$3zOj?nax@A>~*TeU#Qiaf(qXfVP`Z_7;=|P%k0{ epa2xWU$<`tk!?C;hMdp<0000VGd000McNliru-~k2>3JFU#x@rIb0)k0I zK~z}7D>_Y^qsCt6fQsLtNZ|uy(bY_cY)3lu|gQoZ-ac(@heG+7!`r?R_eN zBo5VR9OD#Ze7=xU0suafj7LG3#G$&piu3~^1f-M@Lg>9;Kc^o~#N%0z#G&dBhI-v< zcXE~?G9O9AH#hcj2LNb@CLXf~D-m)Lx#t)no>>QyI8@!B2LSlJxds4`Rfq_Y;TCx> z3C~uD=*#F!$>gScq?B0B6O6|3yWQd>z%#)N!fwz*Lo~5U7yABOTtEn+&(zJFS_E9# zz=hn_5KRDZ5;95ob-?*A7fRc0cCX`w$n50~TjsWNaiKFQi9Ue=x)}1&eKcKrE{pUBL+s^FgL7aGNESLM2st}j z3MFxPNS z9TN$c5)MvdoUIzV$W(Si0EMsP6OswedjhW&e72wPNx`U&6)*(EaNfC z<#J@R*%G^Fu}BtR+e-NSF;A5$`}}U^4~{ZXfTvP!8*sTZqiTG8h7I%^ z$ztjuQGh`y$*Z@L7q+q*WOECX%{?R*0000VGd000McNliru-~j~|4kT&?emwvH0&ht~ zK~z}7ULhhxhI{0@Bq|MYt>}|Xd8Lc()VsB-W;?`zTmL`Ts#39$XfJ%SaL&)-CUkcXW zzwS$GzDL$<+@afPTN1H*doLONRUt9x_b^{9OCa0bN9DKfp1ZDiU_2UH-JTvFEVxTX zYmIKFjl9^~Ln#ipQA}_dCes-z5|H-fdY+E14f;K+@pku70_K3^p_77;v-71;mL_Jt zSYpucVY_?xM*n0wt6i$&LxC4E(mw=#N-?@|_2pIVkX-`2L}0bvMDxY+s2AuxA;j6> z-kGqj7i?iU1H3|jd*Kj?)p`?6rn5?6%F@KtkuMm8l#0(Uui(>Bhy?GNyo8_98NCxx ztJ$d4;|cULFVJc>?96siKsdP1IFUnSg6)_{gbv~0G{*U=VTjDpZU~@q zJ3b+~;JhdBTES;aD$hsf0qWs&IB&0fEaUyar?W33+;@T!9Mb;Sp=Zy8|JA?azxA2Y Uq5R^XT>t<807*qoM6N<$f(x%uf&c&j literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_syringe.png b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_syringe.png new file mode 100644 index 0000000000000000000000000000000000000000..52cfb7e01bc41403f28c19d30950b1bea129e729 GIT binary patch literal 585 zcmV-P0=E5$P)rTNffCl7+FQ7>X0y=~QB{mC-cDV2Htmb|GR2?M8x- zkc2GqK_KKG_y-K)R$aJKFpC-tA#{42Gd4qmUsZ>BnS0ON_c`ax843S!RjXC{X8@ZO zMG=1mh{xj;i9{%u%MqKo_+0~5qESkx(_%0fpxth>*V3*4$z+n&*VY6(ve~TY^?JOt z^hbcM>l9a~(RuTdI`3XnEEc1DK5xO8@LND4k)TJq3K(1FS%RK=f=ni3o6R7835c3K z-(Q@8WDKyicMoo@K1Zce88MFl0)YT=fW>7#49}XG4b!|IiDxfRtJQum^I5wBhr9DbblaQgz3X)DtQTh{PC_b|%RIc;I%s5ex>c>X!9u)a`!7 z#zq(1=G*rlaPadheEigb#B^4nP_TYeUh_w5wOV30Ht*yl&R@KM%QI8ZZfH1ldIARy z9kpZw*jOwUMJN=qvhseYn~QfvX#S3n$7Q%&F7R`xZvX%Q|Nqj`SF`{C00v1!K~w_( XBTcv%L)Xd600000NkvXXu0mjfYOM*6 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_tissue.png b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_tissue.png new file mode 100644 index 0000000000000000000000000000000000000000..ff6f92e86ead274cae498a526a4c493cc3d1f425 GIT binary patch literal 462 zcmV;<0WtoGP)g)fp>8fu6!|}X9RSn!=d1kKWg&BJ z1#tlP*9E0Tax2W_AD+x_W)p zkpW`h89=xP1em=UH2@7kz`nD`?fixQ2f*B!Q3Y_RyJFxkG=w^)mJ=Yr;0X@MNAXcK z#2XqC>O6%e=**~2KoKF`fRKS;qRtR# z$ogz%_6J8RYH}hXqtUR`0T9rcN!aVy&1cp6=Av3i&8oprP|Dtj1pL0n08C6mCbo9c z%C^6xRI;T~smQ}qQQU8L^8E7N9Dq?rBo>pY__QSElagD@$?!;2x;=ePG<b$Xh zXss^oS^j`uTrQW8b^HPV0RR7GZ(YCu000I_L_t&o0LAaW^Ae`>761SM07*qoM6N<$ Ef;GF$Gynhq literal 0 HcmV?d00001 diff --git a/fabricmc/src/main/java/net/cmr/jurassicrevived/JRMod.java b/fabricmc/src/main/java/net/cmr/jurassicrevived/JRMod.java index a2f6468..867a226 100755 --- a/fabricmc/src/main/java/net/cmr/jurassicrevived/JRMod.java +++ b/fabricmc/src/main/java/net/cmr/jurassicrevived/JRMod.java @@ -47,6 +47,11 @@ public class JRMod implements ModInitializer ModBlockEntities.FOSSIL_CLEANER_BE.get() ); + FluidStorage.SIDED.registerForBlockEntities((be, side) -> + new FabricTransferHelper.InternalFluidStorage(((CultivatorBlockEntity) be).getFluidHandler(side)), + ModBlockEntities.CULTIVATOR_BE.get() + ); + ItemStorage.SIDED.registerForBlockEntities((be, side) -> InventoryStorage.of(((GeneratorBlockEntity) be).itemHandler, side), ModBlockEntities.GENERATOR_BE.get() @@ -92,6 +97,11 @@ public class JRMod implements ModInitializer ModBlockEntities.INCUBATOR_BE.get() ); + ItemStorage.SIDED.registerForBlockEntities((be, side) -> + InventoryStorage.of(((CultivatorBlockEntity) be).itemHandler, side), + ModBlockEntities.CULTIVATOR_BE.get() + ); + EnergyStorage.SIDED.registerForBlockEntities((be, side) -> new FabricEnergyWrapper(((PowerCellBlockEntity) be).getEnergyStorage(side)), ModBlockEntities.POWER_CELL_BE.get() @@ -141,5 +151,10 @@ public class JRMod implements ModInitializer new FabricEnergyWrapper(((IncubatorBlockEntity) be).getEnergyStorage(side)), ModBlockEntities.INCUBATOR_BE.get() ); + + EnergyStorage.SIDED.registerForBlockEntities((be, side) -> + new FabricEnergyWrapper(((CultivatorBlockEntity) be).getEnergyStorage(side)), + ModBlockEntities.CULTIVATOR_BE.get() + ); } } diff --git a/fabricmc/src/main/java/net/cmr/jurassicrevived/JRModClient.java b/fabricmc/src/main/java/net/cmr/jurassicrevived/JRModClient.java index d032f7f..7a741fa 100755 --- a/fabricmc/src/main/java/net/cmr/jurassicrevived/JRModClient.java +++ b/fabricmc/src/main/java/net/cmr/jurassicrevived/JRModClient.java @@ -18,9 +18,16 @@ public class JRModClient implements ClientModInitializer { BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.TANK.get(), RenderType.translucent()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.INCUBATOR.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_INCUBATOR.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.CULTIVATOR.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_CULTIVATOR.get(), RenderType.translucent()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DNA_EXTRACTOR.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_DNA_EXTRACTOR.get(), RenderType.translucent()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.FOSSIL_GRINDER.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_FOSSIL_GRINDER.get(), RenderType.translucent()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.FOSSIL_CLEANER.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_FOSSIL_CLEANER.get(), RenderType.translucent()); BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.DNA_HYBRIDIZER.get(), RenderType.translucent()); + BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.WHITE_DNA_HYBRIDIZER.get(), RenderType.translucent()); } }