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 0000000..24676ea Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/alligator_gar_egg.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/coelacanth_egg.png b/common/src/main/resources/assets/jurassicrevived/textures/block/coelacanth_egg.png new file mode 100644 index 0000000..052dd19 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/coelacanth_egg.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/cultivator.png b/common/src/main/resources/assets/jurassicrevived/textures/block/cultivator.png new file mode 100644 index 0000000..51d92f2 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/cultivator.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/cultivator_lit.png b/common/src/main/resources/assets/jurassicrevived/textures/block/cultivator_lit.png new file mode 100644 index 0000000..51d92f2 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/cultivator_lit.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/mawsonia_egg.png b/common/src/main/resources/assets/jurassicrevived/textures/block/mawsonia_egg.png new file mode 100644 index 0000000..4f02f50 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/mawsonia_egg.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator.png b/common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator.png new file mode 100644 index 0000000..23444ce Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator.png differ 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 0000000..23444ce Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/block/white_cultivator_lit.png differ 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 0000000..7ecfad3 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/entity/compsognathus_rebirth.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_dna.png b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_dna.png new file mode 100644 index 0000000..6929b03 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_dna.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_skull_fossil.png b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_skull_fossil.png new file mode 100644 index 0000000..5e7d5d9 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_skull_fossil.png differ 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 0000000..cc69814 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_syringe.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_tissue.png b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_tissue.png new file mode 100644 index 0000000..91b1e7c Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/alligator_gar_tissue.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_dna.png b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_dna.png new file mode 100644 index 0000000..0d9c0fa Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_dna.png differ 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 0000000..e372b30 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_skull_fossil.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_syringe.png b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_syringe.png new file mode 100644 index 0000000..e20481b Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_syringe.png differ 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 0000000..028290f Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/coelacanth_tissue.png differ 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 0000000..722a44f Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_alligator_gar_skull.png differ 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 0000000..e2d2bf0 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_coelacanth_skull.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_mawsonia_skull.png b/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_mawsonia_skull.png new file mode 100644 index 0000000..60bfb8e Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/fresh_mawsonia_skull.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_dna.png b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_dna.png new file mode 100644 index 0000000..67773b5 Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_dna.png differ diff --git a/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_skull_fossil.png b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_skull_fossil.png new file mode 100644 index 0000000..167eb5c Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_skull_fossil.png differ 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 0000000..52cfb7e Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_syringe.png differ 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 0000000..ff6f92e Binary files /dev/null and b/common/src/main/resources/assets/jurassicrevived/textures/item/mawsonia_tissue.png differ 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()); } }