diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/HybridAquaticClient.kt b/src/client/kotlin/dev/hybridlabs/aquatic/HybridAquaticClient.kt index d0bb55189..9513295ee 100644 --- a/src/client/kotlin/dev/hybridlabs/aquatic/HybridAquaticClient.kt +++ b/src/client/kotlin/dev/hybridlabs/aquatic/HybridAquaticClient.kt @@ -8,22 +8,17 @@ import dev.hybridlabs.aquatic.client.network.HybridAquaticClientNetworking import dev.hybridlabs.aquatic.client.render.block.entity.* import dev.hybridlabs.aquatic.client.render.entity.HybridAquaticEntityRenderers import dev.hybridlabs.aquatic.client.render.hud.FishingNetHUDRenderer -import dev.hybridlabs.aquatic.client.render.item.AnemoneBlockItemRenderer -import dev.hybridlabs.aquatic.client.render.item.BuoyBlockItemRenderer -import dev.hybridlabs.aquatic.client.render.item.MessageInABottleBlockItemRenderer +import dev.hybridlabs.aquatic.client.render.item.* import dev.hybridlabs.aquatic.item.HybridAquaticItems import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry -import net.fabricmc.fabric.api.client.rendering.v1.DimensionRenderingRegistry.WeatherRenderer import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback import net.minecraft.client.MinecraftClient import net.minecraft.client.render.RenderLayer -import net.minecraft.client.render.WorldRenderer import net.minecraft.client.render.block.entity.BlockEntityRendererFactories import net.minecraft.client.render.block.entity.BlockEntityRendererFactory -import net.minecraft.world.World object HybridAquaticClient : ClientModInitializer { override fun onInitializeClient() { @@ -36,7 +31,7 @@ object HybridAquaticClient : ClientModInitializer { registerEntityRenderers() registerWeatherRenderers() registerTooltips() - registerHudAddons(); + registerHudAddons() } private fun registerWeatherRenderers() { @@ -63,6 +58,8 @@ object HybridAquaticClient : ClientModInitializer { BlockEntityRendererFactories.register(HybridAquaticBlockEntityTypes.MESSAGE_IN_A_BOTTLE, ::MessageInABottleBlockEntityRenderer) BlockEntityRendererFactories.register(HybridAquaticBlockEntityTypes.FISHING_PLAQUE, ::FishingPlaqueBlockEntityRenderer) BlockEntityRendererFactories.register(HybridAquaticBlockEntityTypes.BUOY, ::BuoyBlockEntityRenderer) + BlockEntityRendererFactories.register(HybridAquaticBlockEntityTypes.HYDROTHERMAL_VENT, ::HydrothermalVentBlockEntityRenderer) + BlockEntityRendererFactories.register(HybridAquaticBlockEntityTypes.CRAB_POT, ::CrabPotBlockEntityRenderer) } private fun registerEntityRenderers() { @@ -72,7 +69,9 @@ object HybridAquaticClient : ClientModInitializer { private fun registerBuiltinItemRenderers(registry: BuiltinItemRendererRegistry = BuiltinItemRendererRegistry.INSTANCE) { registry.register(HybridAquaticItems.ANEMONE, AnemoneBlockItemRenderer()) registry.register(HybridAquaticItems.BUOY, BuoyBlockItemRenderer()) + registry.register(HybridAquaticItems.CRAB_POT, CrabPotBlockItemRenderer()) registry.register(HybridAquaticItems.MESSAGE_IN_A_BOTTLE, MessageInABottleBlockItemRenderer()) + registry.register(HybridAquaticItems.HYDROTHERMAL_VENT, HydrothermalVentBlockItemRenderer()) } fun createBlockEntityRendererFactoryContext(): BlockEntityRendererFactory.Context { diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/client/model/block/entity/CrabPotBlockEntityModel.kt b/src/client/kotlin/dev/hybridlabs/aquatic/client/model/block/entity/CrabPotBlockEntityModel.kt new file mode 100644 index 000000000..de93b3a76 --- /dev/null +++ b/src/client/kotlin/dev/hybridlabs/aquatic/client/model/block/entity/CrabPotBlockEntityModel.kt @@ -0,0 +1,27 @@ +package dev.hybridlabs.aquatic.client.model.block.entity + +import dev.hybridlabs.aquatic.HybridAquatic +import dev.hybridlabs.aquatic.block.entity.BuoyBlockEntity +import dev.hybridlabs.aquatic.block.entity.CrabPotBlockEntity +import net.minecraft.util.Identifier +import software.bernie.geckolib.model.GeoModel + +class CrabPotBlockEntityModel: GeoModel() { + override fun getAnimationResource(entity: CrabPotBlockEntity): Identifier { + return ANIMATION_LOCATION + } + + override fun getModelResource(animatable: CrabPotBlockEntity): Identifier { + return MODEL_LOCATION + } + + override fun getTextureResource(entity: CrabPotBlockEntity): Identifier { + return TEXTURE_LOCATION + } + + companion object { + val ANIMATION_LOCATION = Identifier(HybridAquatic.MOD_ID, "animations/crab_pot.animation.json") + val MODEL_LOCATION = Identifier(HybridAquatic.MOD_ID, "geo/entity/block/crab_pot.geo.json") + val TEXTURE_LOCATION = Identifier(HybridAquatic.MOD_ID, "textures/block/crab_pot.png") + } +} \ No newline at end of file diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/client/model/block/entity/HydrothermalVentBlockEntityModel.kt b/src/client/kotlin/dev/hybridlabs/aquatic/client/model/block/entity/HydrothermalVentBlockEntityModel.kt new file mode 100644 index 000000000..11302ed79 --- /dev/null +++ b/src/client/kotlin/dev/hybridlabs/aquatic/client/model/block/entity/HydrothermalVentBlockEntityModel.kt @@ -0,0 +1,28 @@ +package dev.hybridlabs.aquatic.client.model.block.entity + +import dev.hybridlabs.aquatic.HybridAquatic +import dev.hybridlabs.aquatic.block.entity.BuoyBlockEntity +import dev.hybridlabs.aquatic.block.entity.CrabPotBlockEntity +import dev.hybridlabs.aquatic.block.entity.HydrothermalVentBlockEntity +import net.minecraft.util.Identifier +import software.bernie.geckolib.model.GeoModel + +class HydrothermalVentBlockEntityModel: GeoModel() { + override fun getAnimationResource(entity: HydrothermalVentBlockEntity): Identifier { + return ANIMATION_LOCATION + } + + override fun getModelResource(animatable: HydrothermalVentBlockEntity): Identifier { + return MODEL_LOCATION + } + + override fun getTextureResource(entity: HydrothermalVentBlockEntity): Identifier { + return TEXTURE_LOCATION + } + + companion object { + val ANIMATION_LOCATION = Identifier(HybridAquatic.MOD_ID, "animations/hydrothermal_vent.animation.json") + val MODEL_LOCATION = Identifier(HybridAquatic.MOD_ID, "geo/entity/block/hydrothermal_vent.geo.json") + val TEXTURE_LOCATION = Identifier(HybridAquatic.MOD_ID, "textures/block/hydrothermal_vent.png") + } +} \ No newline at end of file diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/client/render/block/entity/CrabPotBlockEntityRenderer.kt b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/block/entity/CrabPotBlockEntityRenderer.kt new file mode 100644 index 000000000..2d99c1804 --- /dev/null +++ b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/block/entity/CrabPotBlockEntityRenderer.kt @@ -0,0 +1,8 @@ +package dev.hybridlabs.aquatic.client.render.block.entity + +import dev.hybridlabs.aquatic.block.entity.CrabPotBlockEntity +import dev.hybridlabs.aquatic.client.model.block.entity.CrabPotBlockEntityModel +import net.minecraft.client.render.block.entity.BlockEntityRendererFactory.Context +import software.bernie.geckolib.renderer.GeoBlockRenderer + +class CrabPotBlockEntityRenderer(context: Context) : GeoBlockRenderer(CrabPotBlockEntityModel()) \ No newline at end of file diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/client/render/block/entity/HydrothermalVentBlockEntityRenderer.kt b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/block/entity/HydrothermalVentBlockEntityRenderer.kt new file mode 100644 index 000000000..089c54290 --- /dev/null +++ b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/block/entity/HydrothermalVentBlockEntityRenderer.kt @@ -0,0 +1,8 @@ +package dev.hybridlabs.aquatic.client.render.block.entity + +import dev.hybridlabs.aquatic.block.entity.HydrothermalVentBlockEntity +import dev.hybridlabs.aquatic.client.model.block.entity.HydrothermalVentBlockEntityModel +import net.minecraft.client.render.block.entity.BlockEntityRendererFactory.Context +import software.bernie.geckolib.renderer.GeoBlockRenderer + +class HydrothermalVentBlockEntityRenderer(context: Context) : GeoBlockRenderer(HydrothermalVentBlockEntityModel()) \ No newline at end of file diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/client/render/item/CrabPotBlockItemRenderer.kt b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/item/CrabPotBlockItemRenderer.kt new file mode 100644 index 000000000..82106dd4b --- /dev/null +++ b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/item/CrabPotBlockItemRenderer.kt @@ -0,0 +1,30 @@ +package dev.hybridlabs.aquatic.client.render.item + +import dev.hybridlabs.aquatic.HybridAquaticClient +import dev.hybridlabs.aquatic.block.HybridAquaticBlocks +import dev.hybridlabs.aquatic.block.entity.BuoyBlockEntity +import dev.hybridlabs.aquatic.block.entity.CrabPotBlockEntity +import dev.hybridlabs.aquatic.client.render.block.entity.BuoyBlockEntityRenderer +import dev.hybridlabs.aquatic.client.render.block.entity.CrabPotBlockEntityRenderer +import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry.DynamicItemRenderer +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import net.minecraft.util.math.BlockPos + +class CrabPotBlockItemRenderer: DynamicItemRenderer { + private val crabPotBlockEntity = CrabPotBlockEntity(BlockPos.ORIGIN, HybridAquaticBlocks.CRAB_POT.defaultState) + private val renderer = CrabPotBlockEntityRenderer(HybridAquaticClient.createBlockEntityRendererFactoryContext()) + + override fun render( + stack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + renderer.render(crabPotBlockEntity, 1.0f, matrices, vertexConsumers, light, overlay) + } +} \ No newline at end of file diff --git a/src/client/kotlin/dev/hybridlabs/aquatic/client/render/item/HydrothermalVentBlockItemRenderer.kt b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/item/HydrothermalVentBlockItemRenderer.kt new file mode 100644 index 000000000..9c8d5af2a --- /dev/null +++ b/src/client/kotlin/dev/hybridlabs/aquatic/client/render/item/HydrothermalVentBlockItemRenderer.kt @@ -0,0 +1,31 @@ +package dev.hybridlabs.aquatic.client.render.item + +import dev.hybridlabs.aquatic.HybridAquaticClient +import dev.hybridlabs.aquatic.block.HybridAquaticBlocks +import dev.hybridlabs.aquatic.block.entity.BuoyBlockEntity +import dev.hybridlabs.aquatic.block.entity.CrabPotBlockEntity +import dev.hybridlabs.aquatic.block.entity.HydrothermalVentBlockEntity +import dev.hybridlabs.aquatic.client.render.block.entity.BuoyBlockEntityRenderer +import dev.hybridlabs.aquatic.client.render.block.entity.HydrothermalVentBlockEntityRenderer +import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry.DynamicItemRenderer +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.item.ItemStack +import net.minecraft.util.math.BlockPos + +class HydrothermalVentBlockItemRenderer: DynamicItemRenderer { + private val hydrothermalVentBlockEntity = HydrothermalVentBlockEntity(BlockPos.ORIGIN, HybridAquaticBlocks.HYDROTHERMAL_VENT.defaultState) + private val renderer = HydrothermalVentBlockEntityRenderer(HybridAquaticClient.createBlockEntityRendererFactoryContext()) + + override fun render( + stack: ItemStack, + mode: ModelTransformationMode, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + renderer.render(hydrothermalVentBlockEntity, 1.0f, matrices, vertexConsumers, light, overlay) + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/hybrid-aquatic/lang/en_us.json b/src/generated/resources/assets/hybrid-aquatic/lang/en_us.json index d092380e5..e7f271d61 100644 --- a/src/generated/resources/assets/hybrid-aquatic/lang/en_us.json +++ b/src/generated/resources/assets/hybrid-aquatic/lang/en_us.json @@ -3,11 +3,13 @@ "block.hybrid-aquatic.basking_shark_plushie": "Basking Shark Plushie", "block.hybrid-aquatic.bull_shark_plushie": "Bull Shark Plushie", "block.hybrid-aquatic.buoy": "Buoy", + "block.hybrid-aquatic.crab_pot": "Crab Pot", "block.hybrid-aquatic.crate": "Crate", "block.hybrid-aquatic.crate.description": "Break with an axe to open", "block.hybrid-aquatic.frilled_shark_plushie": "Frilled Shark Plushie", "block.hybrid-aquatic.great_white_shark_plushie": "Great White Shark Plushie", "block.hybrid-aquatic.hammerhead_shark_plushie": "Hammerhead Shark Plushie", + "block.hybrid-aquatic.hydrothermal_vent": "Hydrothermal Vent", "block.hybrid-aquatic.message_in_a_bottle": "Message in a Bottle", "block.hybrid-aquatic.message_in_a_bottle.jar": "Message in a Jar", "block.hybrid-aquatic.message_in_a_bottle.longneck": "Message in a Longneck Bottle", @@ -51,6 +53,7 @@ "entity.hybrid-aquatic.hammerhead_shark": "Hammerhead Shark", "entity.hybrid-aquatic.hermit_crab": "Hermit Crab", "entity.hybrid-aquatic.horseshoe_crab": "Horseshoe Crab", + "entity.hybrid-aquatic.karkinos": "Karkinos", "entity.hybrid-aquatic.lightfoot_crab": "Lightfoot Crab", "entity.hybrid-aquatic.lionfish": "Lionfish", "entity.hybrid-aquatic.lions_mane_jellyfish": "Lion's Mane Jellyfish", @@ -168,6 +171,7 @@ "item.hybrid-aquatic.hermit_crab_spawn_egg": "Hermit Crab Spawn Egg", "item.hybrid-aquatic.hook.description": "Needs to be put in the offhand", "item.hybrid-aquatic.horseshoe_crab_spawn_egg": "Horseshoe Crab Spawn Egg", + "item.hybrid-aquatic.karkinos_spawn_egg": "Karkinos Spawn Egg", "item.hybrid-aquatic.lightfoot_crab_spawn_egg": "Lightfoot Crab Spawn Egg", "item.hybrid-aquatic.lionfish": "Lionfish", "item.hybrid-aquatic.lionfish_spawn_egg": "Lionfish Spawn Egg", diff --git a/src/generated/resources/data/hybrid-aquatic/loot_tables/blocks/crab_pot.json b/src/generated/resources/data/hybrid-aquatic/loot_tables/blocks/crab_pot.json new file mode 100644 index 000000000..a09eca0d3 --- /dev/null +++ b/src/generated/resources/data/hybrid-aquatic/loot_tables/blocks/crab_pot.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "hybrid-aquatic:crab_pot" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/hybrid-aquatic/loot_tables/blocks/hydrothermal_vent.json b/src/generated/resources/data/hybrid-aquatic/loot_tables/blocks/hydrothermal_vent.json new file mode 100644 index 000000000..c00514ffc --- /dev/null +++ b/src/generated/resources/data/hybrid-aquatic/loot_tables/blocks/hydrothermal_vent.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "hybrid-aquatic:hydrothermal_vent" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/hybrid-aquatic/tags/blocks/hydrothermal_vent_generate_in.json b/src/generated/resources/data/hybrid-aquatic/tags/blocks/hydrothermal_vent_generate_in.json new file mode 100644 index 000000000..3d6f6d564 --- /dev/null +++ b/src/generated/resources/data/hybrid-aquatic/tags/blocks/hydrothermal_vent_generate_in.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:water" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/hybrid-aquatic/tags/worldgen/biome/hydrothermal_vent_spawn_biomes.json b/src/generated/resources/data/hybrid-aquatic/tags/worldgen/biome/hydrothermal_vent_spawn_biomes.json new file mode 100644 index 000000000..e8cec0d64 --- /dev/null +++ b/src/generated/resources/data/hybrid-aquatic/tags/worldgen/biome/hydrothermal_vent_spawn_biomes.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + "minecraft:deep_ocean", + "minecraft:deep_frozen_ocean", + "minecraft:deep_cold_ocean", + "minecraft:deep_lukewarm_ocean" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/hybrid-aquatic/worldgen/configured_feature/hydrothermal_vents.json b/src/generated/resources/data/hybrid-aquatic/worldgen/configured_feature/hydrothermal_vents.json new file mode 100644 index 000000000..d536b325d --- /dev/null +++ b/src/generated/resources/data/hybrid-aquatic/worldgen/configured_feature/hydrothermal_vents.json @@ -0,0 +1,33 @@ +{ + "type": "minecraft:random_patch", + "config": { + "feature": { + "feature": { + "type": "minecraft:simple_block", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "hybrid-aquatic:hydrothermal_vent", + "Properties": { + "waterlogged": "true" + } + } + } + } + }, + "placement": [ + { + "type": "minecraft:block_predicate_filter", + "predicate": { + "type": "minecraft:matching_block_tag", + "tag": "hybrid-aquatic:hydrothermal_vent_generate_in" + } + } + ] + }, + "tries": 6, + "xz_spread": 2, + "y_spread": 2 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/hybrid-aquatic/worldgen/placed_feature/hydrothermal_vents.json b/src/generated/resources/data/hybrid-aquatic/worldgen/placed_feature/hydrothermal_vents.json new file mode 100644 index 000000000..8ee797434 --- /dev/null +++ b/src/generated/resources/data/hybrid-aquatic/worldgen/placed_feature/hydrothermal_vents.json @@ -0,0 +1,19 @@ +{ + "feature": "hybrid-aquatic:hydrothermal_vents", + "placement": [ + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "OCEAN_FLOOR_WG" + }, + { + "type": "minecraft:count", + "count": 1 + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/AnemoneBlock.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/AnemoneBlock.kt index b5627f46a..f214dae1f 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/block/AnemoneBlock.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/AnemoneBlock.kt @@ -115,4 +115,4 @@ class AnemoneBlock(settings: Settings) : PlantBlock(settings), BlockEntityProvid private val SHAPE = createCuboidShape(1.0, 0.0, 1.0, 15.0, 16.0, 15.0) private val COLLISION_SHAPE = createCuboidShape(1.0, 0.0, 1.0, 15.0, 8.0, 15.0) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/CrabPotBlock.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/CrabPotBlock.kt new file mode 100644 index 000000000..49d79b74e --- /dev/null +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/CrabPotBlock.kt @@ -0,0 +1,80 @@ +@file:Suppress("OVERRIDE_DEPRECATION") + +package dev.hybridlabs.aquatic.block + +import dev.hybridlabs.aquatic.block.entity.CrabPotBlockEntity +import net.minecraft.block.* +import net.minecraft.block.entity.BlockEntity +import net.minecraft.fluid.FluidState +import net.minecraft.fluid.Fluids +import net.minecraft.item.ItemPlacementContext +import net.minecraft.registry.tag.FluidTags +import net.minecraft.state.StateManager +import net.minecraft.state.property.Properties +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.util.shape.VoxelShape +import net.minecraft.world.BlockView +import net.minecraft.world.WorldAccess +import net.minecraft.world.WorldView + +open class CrabPotBlock(settings: Settings): Block(settings), BlockEntityProvider, Waterloggable { + init { + defaultState = stateManager.defaultState.with(Properties.WATERLOGGED, false) + } + + override fun getRenderType(state: BlockState): BlockRenderType { + return BlockRenderType.ENTITYBLOCK_ANIMATED + } + + override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity { + return CrabPotBlockEntity(pos, state) + } + + override fun getPlacementState(ctx: ItemPlacementContext): BlockState? { + val fluidState = ctx.world.getFluidState(ctx.blockPos) + return if (fluidState.isIn(FluidTags.WATER)) defaultState.with( + Properties.WATERLOGGED, ctx.world.getFluidState(ctx.blockPos).isOf( + Fluids.WATER)) else null + } + + override fun getFluidState(state: BlockState): FluidState { + return if (state.get(Properties.WATERLOGGED)) Fluids.WATER.getStill(false) else super.getFluidState(state) + } + + override fun getStateForNeighborUpdate( + state: BlockState, + direction: Direction, + neighborState: BlockState, + world: WorldAccess, + pos: BlockPos, + neighborPos: BlockPos + ): BlockState { + return if (canPlaceAt(state, world, pos)) super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos) + else Blocks.AIR.defaultState + } + + override fun appendProperties(builder: StateManager.Builder) { + builder.add(Properties.WATERLOGGED) + } + + override fun getOutlineShape( + state: BlockState, + world: BlockView, + pos: BlockPos, + context: ShapeContext + ): VoxelShape { + return SHAPE + } + + override fun canPlaceAt(state: BlockState, world: WorldView, pos: BlockPos): Boolean { + val placedOn = world.getBlockState(pos) + val isAirAbove = world.getBlockState(pos.up()).isAir && world.getBlockState(pos.up(2)).isAir + + return placedOn.fluidState.isOf(Fluids.WATER) && isAirAbove + } + + companion object { + val SHAPE: VoxelShape = createCuboidShape(1.0, 3.0, 1.0, 15.0, 16.0, 15.0) + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/HybridAquaticBlocks.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/HybridAquaticBlocks.kt index 7e10657c2..830e06ffc 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/block/HybridAquaticBlocks.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/HybridAquaticBlocks.kt @@ -47,11 +47,17 @@ object HybridAquaticBlocks { val CRATE = register("crate", CrateBlock(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS))) + val CRAB_POT = register("crab_pot", CrabPotBlock(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS))) + val BUOY = register("buoy", BuoyBlock(FabricBlockSettings.copyOf(Blocks.OAK_PLANKS) .nonOpaque() .luminance(15) )) + val HYDROTHERMAL_VENT = register("hydrothermal_vent", HydrothermalVentBlock(FabricBlockSettings.copyOf(Blocks.MAGMA_BLOCK) + .nonOpaque() + )) + private fun createPlushieBlock(variant: PlushieBlock.Variant, particleBlock: Block): PlushieBlock { return PlushieBlock(variant, particleBlock, FabricBlockSettings.create() @@ -62,7 +68,6 @@ object HybridAquaticBlocks { ) } - val FISHING_PLAQUE = register("fishing_plaque", FishingPlaque(FabricBlockSettings.create())) diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/HydrothermalVentBlock.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/HydrothermalVentBlock.kt new file mode 100644 index 000000000..0819ac59b --- /dev/null +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/HydrothermalVentBlock.kt @@ -0,0 +1,119 @@ +package dev.hybridlabs.aquatic.block + +import dev.hybridlabs.aquatic.block.entity.HydrothermalVentBlockEntity +import dev.hybridlabs.aquatic.entity.critter.YetiCrabEntity +import net.minecraft.block.* +import net.minecraft.block.entity.BlockEntity +import net.minecraft.entity.Entity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.effect.StatusEffectInstance +import net.minecraft.entity.effect.StatusEffects +import net.minecraft.fluid.FluidState +import net.minecraft.fluid.Fluids +import net.minecraft.item.ItemPlacementContext +import net.minecraft.particle.ParticleTypes +import net.minecraft.registry.tag.FluidTags +import net.minecraft.state.StateManager +import net.minecraft.state.property.Properties +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.util.math.random.Random +import net.minecraft.util.shape.VoxelShape +import net.minecraft.world.BlockView +import net.minecraft.world.World +import net.minecraft.world.WorldAccess + +@Suppress("DEPRECATION") +class HydrothermalVentBlock(settings: Settings) : PlantBlock(settings), BlockEntityProvider, Waterloggable { + init { + defaultState = stateManager.defaultState.with(Properties.WATERLOGGED, false) + } + + override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) { + if (!world.isClient && entity is LivingEntity && entity !is YetiCrabEntity) { + entity.addStatusEffect(StatusEffectInstance(StatusEffects.WITHER, 100, 1)) + entity.addStatusEffect(StatusEffectInstance(StatusEffects.DARKNESS, 100, 2)) + } + } + + override fun randomDisplayTick(state: BlockState?, world: World?, pos: BlockPos?, random: Random?) { + super.randomDisplayTick(state, world, pos, random) + if (world != null && pos != null) { + spawnSmokeParticle(world, pos) + } + } + private fun spawnSmokeParticle(world: World, pos: BlockPos) { + val random = world.random + val defaultParticleType = ParticleTypes.CAMPFIRE_COSY_SMOKE + + world.addParticle( + defaultParticleType, + pos.x.toDouble() + 0.5 + random.nextDouble() / 3.0 * (if (random.nextBoolean()) 1 else -1).toDouble(), + pos.y.toDouble() + random.nextDouble() + random.nextDouble(), + pos.z.toDouble() + 0.5 + random.nextDouble() / 3.0 * (if (random.nextBoolean()) 1 else -1).toDouble(), + 0.0, + 0.07, + 0.0 + ) + } + + override fun canPlantOnTop(floor: BlockState, world: BlockView, pos: BlockPos): Boolean { + return !floor.getCollisionShape(world, pos).getFace(Direction.UP).isEmpty || floor.isSideSolidFullSquare(world, pos, Direction.UP) + } + + override fun getCollisionShape( + state: BlockState, + world: BlockView, + pos: BlockPos, + context: ShapeContext + ): VoxelShape { + return COLLISION_SHAPE + } + + override fun getStateForNeighborUpdate( + state: BlockState, + direction: Direction, + neighborState: BlockState, + world: WorldAccess, + pos: BlockPos, + neighborPos: BlockPos + ): BlockState { + if (state.get(Properties.WATERLOGGED)) { + world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)) + } + + return if (!canPlaceAt(state, world, pos)) { + Blocks.AIR.defaultState + } else super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos) + } + + override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape { + return SHAPE + } + + override fun getPlacementState(ctx: ItemPlacementContext): BlockState? { + val fluidState = ctx.world.getFluidState(ctx.blockPos) + return if (fluidState.isIn(FluidTags.WATER)) defaultState.with(Properties.WATERLOGGED, ctx.world.getFluidState(ctx.blockPos).isOf(Fluids.WATER)) else null + } + + override fun getFluidState(state: BlockState): FluidState { + return if (state.get(Properties.WATERLOGGED)) Fluids.WATER.getStill(false) else super.getFluidState(state) + } + + override fun getRenderType(state: BlockState): BlockRenderType { + return BlockRenderType.ENTITYBLOCK_ANIMATED + } + + override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity { + return HydrothermalVentBlockEntity(pos, state) + } + + override fun appendProperties(builder: StateManager.Builder) { + builder.add(Properties.WATERLOGGED) + } + + companion object { + private val SHAPE = createCuboidShape(2.0, 0.0, 2.0, 14.0, 12.0, 14.0) + private val COLLISION_SHAPE = createCuboidShape(2.0, 1.0, 2.0, 14.0, 12.0, 14.0) + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/CrabPotBlockEntity.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/CrabPotBlockEntity.kt new file mode 100644 index 000000000..db14d1bc6 --- /dev/null +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/CrabPotBlockEntity.kt @@ -0,0 +1,47 @@ +package dev.hybridlabs.aquatic.block.entity + +import net.minecraft.block.BlockState +import net.minecraft.block.entity.BlockEntity +import net.minecraft.util.math.BlockPos +import software.bernie.geckolib.core.animatable.GeoAnimatable +import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache +import software.bernie.geckolib.core.animation.* +import software.bernie.geckolib.core.`object`.PlayState +import software.bernie.geckolib.util.GeckoLibUtil +import software.bernie.geckolib.util.RenderUtils + + +class CrabPotBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(HybridAquaticBlockEntityTypes.CRAB_POT, pos, state), GeoAnimatable { + private val animCache = GeckoLibUtil.createInstanceCache(this) + + private fun predicate(event: AnimationState): PlayState where E : BlockEntity?, E : GeoAnimatable { + return if (world != null) { + event.controller.setAnimation(RawAnimation.begin().then("float", Animation.LoopType.LOOP)) + PlayState.CONTINUE + } else { + PlayState.STOP + } + } + override fun registerControllers(controllerRegistrar: AnimatableManager.ControllerRegistrar) { + controllerRegistrar.add( + AnimationController( + this, + "controller", + 0, + ::predicate + ) + ) + } + + override fun getAnimatableInstanceCache(): AnimatableInstanceCache { + return animCache + } + + override fun getTick(p0: Any?): Double { + return RenderUtils.getCurrentTick() + } + + companion object { + val BOB_ANIMATION: RawAnimation = RawAnimation.begin().thenLoop("water_bob") + } +} diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HybridAquaticBlockEntityTypes.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HybridAquaticBlockEntityTypes.kt index 991ed9997..f845e840a 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HybridAquaticBlockEntityTypes.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HybridAquaticBlockEntityTypes.kt @@ -2,6 +2,7 @@ package dev.hybridlabs.aquatic.block.entity import dev.hybridlabs.aquatic.HybridAquatic import dev.hybridlabs.aquatic.block.HybridAquaticBlocks +import dev.hybridlabs.aquatic.block.HydrothermalVentBlock import net.fabricmc.fabric.api.`object`.builder.v1.block.entity.FabricBlockEntityTypeBuilder import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntityType @@ -16,6 +17,8 @@ object HybridAquaticBlockEntityTypes { val MESSAGE_IN_A_BOTTLE: BlockEntityType = register("message_in_a_bottle", FabricBlockEntityTypeBuilder.create(::MessageInABottleBlockEntity, HybridAquaticBlocks.MESSAGE_IN_A_BOTTLE)) val FISHING_PLAQUE: BlockEntityType = register("fishing_plaque", FabricBlockEntityTypeBuilder.create(::FishingPlaqueBlockEntity, HybridAquaticBlocks.FISHING_PLAQUE)) val BUOY: BlockEntityType = register("buoy", FabricBlockEntityTypeBuilder.create(::BuoyBlockEntity, HybridAquaticBlocks.BUOY)) + val CRAB_POT: BlockEntityType = register("crab_pot", FabricBlockEntityTypeBuilder.create(::CrabPotBlockEntity, HybridAquaticBlocks.CRAB_POT)) + val HYDROTHERMAL_VENT: BlockEntityType = register("hydrothermal_vent", FabricBlockEntityTypeBuilder.create(::HydrothermalVentBlockEntity, HybridAquaticBlocks.HYDROTHERMAL_VENT)) private fun register(id: String, builder: FabricBlockEntityTypeBuilder): BlockEntityType { val identifier = Identifier(HybridAquatic.MOD_ID, id) diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HydrothermalVentBlockEntity.kt b/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HydrothermalVentBlockEntity.kt new file mode 100644 index 000000000..bf6872c5d --- /dev/null +++ b/src/main/kotlin/dev/hybridlabs/aquatic/block/entity/HydrothermalVentBlockEntity.kt @@ -0,0 +1,45 @@ +package dev.hybridlabs.aquatic.block.entity + +import net.minecraft.block.BlockState +import net.minecraft.block.entity.BlockEntity +import net.minecraft.nbt.NbtCompound +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket +import net.minecraft.util.math.BlockPos +import software.bernie.geckolib.core.animatable.GeoAnimatable +import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache +import software.bernie.geckolib.core.animation.* +import software.bernie.geckolib.core.`object`.PlayState +import software.bernie.geckolib.util.GeckoLibUtil +import software.bernie.geckolib.util.RenderUtils + +class HydrothermalVentBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(HybridAquaticBlockEntityTypes.HYDROTHERMAL_VENT, pos, state), GeoAnimatable { + private val factory = GeckoLibUtil.createInstanceCache(this) + private fun predicate(event: AnimationState): PlayState where E : BlockEntity?, E : GeoAnimatable { + return if (world != null) { + event.controller.setAnimation(RawAnimation.begin().then("float", Animation.LoopType.LOOP)) + PlayState.CONTINUE + } else { + PlayState.STOP + } + } + + override fun registerControllers(controllerRegistrar: AnimatableManager.ControllerRegistrar) { + controllerRegistrar.add(AnimationController(this, "controller", 0, ::predicate)) + } + + override fun getAnimatableInstanceCache(): AnimatableInstanceCache { + return factory + } + + override fun getTick(o: Any): Double { + return RenderUtils.getCurrentTick() + } + + override fun toInitialChunkDataNbt(): NbtCompound { + return createNbt() + } + + override fun toUpdatePacket(): BlockEntityUpdateS2CPacket { + return BlockEntityUpdateS2CPacket.create(this) + } +} diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/data/client/LanguageProvider.kt b/src/main/kotlin/dev/hybridlabs/aquatic/data/client/LanguageProvider.kt index 46aac8d7d..b560bb5ff 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/data/client/LanguageProvider.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/data/client/LanguageProvider.kt @@ -65,6 +65,8 @@ class LanguageProvider(output: FabricDataOutput) : FabricLanguageProvider(output HybridAquaticBlocks.ANEMONE to "Anemone", HybridAquaticBlocks.CRATE to "Crate", HybridAquaticBlocks.BUOY to "Buoy", + HybridAquaticBlocks.CRAB_POT to "Crab Pot", + HybridAquaticBlocks.HYDROTHERMAL_VENT to "Hydrothermal Vent", ).forEach { (block, translation) -> builder.add(block, translation) } @@ -218,6 +220,7 @@ class LanguageProvider(output: FabricDataOutput) : FabricLanguageProvider(output HybridAquaticEntityTypes.LIONS_MANE_JELLYFISH to "Lion's Mane Jellyfish", HybridAquaticEntityTypes.ATOLLA_JELLYFISH to "Atolla Jellyfish", HybridAquaticEntityTypes.BLUE_JELLYFISH to "Blue Jellyfish", + HybridAquaticEntityTypes.KARKINOS to "Karkinos", ) // verify display name list is valid diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/ConfiguredFeatureProvider.kt b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/ConfiguredFeatureProvider.kt index 243bf3a5e..13d49dd97 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/ConfiguredFeatureProvider.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/ConfiguredFeatureProvider.kt @@ -40,6 +40,23 @@ class ConfiguredFeatureProvider(output: FabricDataOutput, registriesFuture: Comp ) ) + // hydrothermal vents + entries.add( + HybridAquaticConfiguredFeatures.HYDROTHERMAL_VENTS, + ConfiguredFeature( + Feature.RANDOM_PATCH, RandomPatchFeatureConfig( + 6, 2, 2, + PlacedFeatures.createEntry( + Feature.SIMPLE_BLOCK, + SimpleBlockFeatureConfig( + BlockStateProvider.of(HybridAquaticBlocks.HYDROTHERMAL_VENT.defaultState.with(Properties.WATERLOGGED, true)) + ), + BlockPredicate.matchingBlockTag(HybridAquaticBlockTags.HYDROTHERMAL_VENT_GENERATE_IN) + ) + ) + ) + ) + // message in a bottle entries.add( HybridAquaticConfiguredFeatures.MESSAGE_IN_A_BOTTLE, diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/PlacedFeatureProvider.kt b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/PlacedFeatureProvider.kt index 1006b9c38..b8ad96bef 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/PlacedFeatureProvider.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/PlacedFeatureProvider.kt @@ -30,6 +30,19 @@ class PlacedFeatureProvider(output: FabricDataOutput, registriesFuture: Completa ) ) + // hydrothermal vents + entries.add( + HybridAquaticPlacedFeatures.HYDROTHERMAL_VENTS, + PlacedFeature(entries.ref(HybridAquaticConfiguredFeatures.HYDROTHERMAL_VENTS), + listOf( + SquarePlacementModifier.of(), + PlacedFeatures.OCEAN_FLOOR_WG_HEIGHTMAP, + CountPlacementModifier.of(1), + BiomePlacementModifier.of() + ) + ) + ) + // message in a botle entries.add( HybridAquaticPlacedFeatures.MESSAGE_IN_A_BOTTLE, diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BiomeTagProvider.kt b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BiomeTagProvider.kt index f798a5e0d..a11ed38af 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BiomeTagProvider.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BiomeTagProvider.kt @@ -520,6 +520,13 @@ class BiomeTagProvider(output: FabricDataOutput, registriesFuture: CompletableFu BiomeKeys.WARM_OCEAN ) + getOrCreateTagBuilder(HybridAquaticBiomeTags.HYDROTHERMAL_VENT_SPAWN_BIOMES).add( + BiomeKeys.DEEP_OCEAN, + BiomeKeys.DEEP_FROZEN_OCEAN, + BiomeKeys.DEEP_COLD_OCEAN, + BiomeKeys.DEEP_LUKEWARM_OCEAN + ) + getOrCreateTagBuilder(HybridAquaticBiomeTags.MESSAGE_IN_A_BOTTLE_SPAWN_BIOMES) .forceAddTag(BiomeTags.IS_OCEAN) .forceAddTag(BiomeTags.IS_BEACH) diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BlockTagProvider.kt b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BlockTagProvider.kt index 27cce9cdf..5f1357a85 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BlockTagProvider.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/data/server/tag/BlockTagProvider.kt @@ -16,6 +16,9 @@ class BlockTagProvider(output: FabricDataOutput, registriesFuture: CompletableFu getOrCreateTagBuilder(HybridAquaticBlockTags.ANEMONES_GENERATE_IN) .add(Blocks.WATER) + getOrCreateTagBuilder(HybridAquaticBlockTags.HYDROTHERMAL_VENT_GENERATE_IN) + .add(Blocks.WATER) + getOrCreateTagBuilder(HybridAquaticBlockTags.MESSAGE_IN_A_BOTTLE_SPAWNS_IN) .add(Blocks.WATER) diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/entity/critter/YetiCrabEntity.kt b/src/main/kotlin/dev/hybridlabs/aquatic/entity/critter/YetiCrabEntity.kt index 9841220f2..b1d56b2ac 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/entity/critter/YetiCrabEntity.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/entity/critter/YetiCrabEntity.kt @@ -1,13 +1,19 @@ package dev.hybridlabs.aquatic.entity.critter +import dev.hybridlabs.aquatic.block.HybridAquaticBlocks import net.minecraft.entity.EntityType import net.minecraft.entity.attribute.DefaultAttributeContainer import net.minecraft.entity.attribute.EntityAttributes import net.minecraft.entity.mob.WaterCreatureEntity +import net.minecraft.registry.tag.BlockTags +import net.minecraft.util.math.BlockPos import net.minecraft.world.World class YetiCrabEntity(entityType: EntityType, world: World) : HybridAquaticCrabEntity(entityType, world) { + + private var targetVentPos: BlockPos? = null + companion object { fun createMobAttributes(): DefaultAttributeContainer.Builder { return WaterCreatureEntity.createMobAttributes() @@ -25,7 +31,49 @@ class YetiCrabEntity(entityType: EntityType, wor override fun getMinSize(): Int { return -5 - }override fun isSneaking(): Boolean { + } + + override fun isSneaking(): Boolean { return true } + + override fun tick() { + super.tick() + + if (targetVentPos == null || world.getBlockState(targetVentPos).isOf(HybridAquaticBlocks.HYDROTHERMAL_VENT)) { + targetVentPos = findNearbyVentBlock() + } + + if (targetVentPos != null) { + val distanceToVent = distanceTo(targetVentPos!!) + + if (distanceToVent > 5.0) { + navigateToVent(targetVentPos!!) + } + } + } + + private fun navigateToVent(ventBlockPos: BlockPos) { + this.navigation.startMovingTo(ventBlockPos.x.toDouble(), ventBlockPos.y.toDouble(), ventBlockPos.z.toDouble(), this.getAttributeValue(EntityAttributes.GENERIC_MOVEMENT_SPEED)) + } + + private fun findNearbyVentBlock(): BlockPos? { + for (i in -5..5) { + for (j in -5..5) { + for (k in -5..5) { + val blockPos = BlockPos((x + i).toInt(), (y + j).toInt(), (z + k).toInt()) + val blockState = world.getBlockState(blockPos) + + if (blockState.isOf(HybridAquaticBlocks.HYDROTHERMAL_VENT)) { + return blockPos + } + } + } + } + return null + } + + private fun distanceTo(pos: BlockPos): Double { + return this.blockPos.getSquaredDistance(pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble()) + } } \ No newline at end of file diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItemGroups.kt b/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItemGroups.kt index e31e15ce3..e9164a4a3 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItemGroups.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItemGroups.kt @@ -89,6 +89,8 @@ object HybridAquaticItemGroups { entries.add(HybridAquaticItems.FISHING_NET) entries.add(HybridAquaticItems.BUOY) + entries.add(HybridAquaticItems.CRAB_POT) + entries.add(HybridAquaticItems.HYDROTHERMAL_VENT) // spawn eggs Registries.ITEM.forEach { item -> diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItems.kt b/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItems.kt index 9d76269f9..3deb2ad5b 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItems.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/item/HybridAquaticItems.kt @@ -21,6 +21,8 @@ object HybridAquaticItems { val ANEMONE = registerBlockItem("anemone", HybridAquaticBlocks.ANEMONE) val FISHING_PLAQUE = registerBlockItem("fishing_plaque", HybridAquaticBlocks.FISHING_PLAQUE) val BUOY = registerPlaceableInWaterBlockItem("buoy", HybridAquaticBlocks.BUOY) + val CRAB_POT = registerPlaceableInWaterBlockItem("crab_pot", HybridAquaticBlocks.CRAB_POT) + val HYDROTHERMAL_VENT = registerPlaceableInWaterBlockItem("hydrothermal_vent", HybridAquaticBlocks.HYDROTHERMAL_VENT) val MESSAGE_IN_A_BOTTLE = register("message_in_a_bottle", MessageInABottleItem(FabricItemSettings())) val FISHING_NET = register("fishing_net", FishingNetItem(FabricItemSettings().maxCount(1))) diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBiomeTags.kt b/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBiomeTags.kt index f6a99b0a0..df5dd9f85 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBiomeTags.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBiomeTags.kt @@ -87,6 +87,7 @@ object HybridAquaticBiomeTags { val ANEMONE_SPAWN_BIOMES = create("anemone_spawn_biomes") val MESSAGE_IN_A_BOTTLE_SPAWN_BIOMES = create("message_in_a_bottle_spawn_biomes") + val HYDROTHERMAL_VENT_SPAWN_BIOMES = create("hydrothermal_vent_spawn_biomes") private fun create(id: String): TagKey { return TagKey.of(RegistryKeys.BIOME, Identifier(HybridAquatic.MOD_ID, id)) diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBlockTags.kt b/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBlockTags.kt index 90a7a9ac8..854c050e5 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBlockTags.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/tag/HybridAquaticBlockTags.kt @@ -17,6 +17,11 @@ object HybridAquaticBlockTags { */ val ANEMONES_GENERATE_IN = create("anemones_generate_in") + /** + * A list of blocks that hydrothermal vents can generate inside of. + */ + val HYDROTHERMAL_VENT_GENERATE_IN = create("hydrothermal_vent_generate_in") + /** * A list of blocks that message in a bottles can generate inside of. */ diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/FeatureBiomeModifications.kt b/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/FeatureBiomeModifications.kt index 69c0b7c9e..30af960da 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/FeatureBiomeModifications.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/FeatureBiomeModifications.kt @@ -15,6 +15,11 @@ object FeatureBiomeModifications { GenerationStep.Feature.VEGETAL_DECORATION, HybridAquaticPlacedFeatures.ANEMONE_PATCH ) + BiomeModifications.addFeature( + BiomeSelectors.tag(HybridAquaticBiomeTags.HYDROTHERMAL_VENT_SPAWN_BIOMES), + GenerationStep.Feature.VEGETAL_DECORATION, + HybridAquaticPlacedFeatures.HYDROTHERMAL_VENTS + ) BiomeModifications.addFeature( BiomeSelectors.tag(HybridAquaticBiomeTags.MESSAGE_IN_A_BOTTLE_SPAWN_BIOMES), diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticConfiguredFeatures.kt b/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticConfiguredFeatures.kt index 1f973fab7..32e5aec9a 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticConfiguredFeatures.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticConfiguredFeatures.kt @@ -14,6 +14,11 @@ object HybridAquaticConfiguredFeatures { * A patch of anemones. */ val ANEMONE_PATCH = register("anemone_patch") + /** + * + * A patch of vents. + */ + val HYDROTHERMAL_VENTS= register("hydrothermal_vents") /** * A message in a bottle. diff --git a/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticPlacedFeatures.kt b/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticPlacedFeatures.kt index 29527a680..1b41aa24a 100644 --- a/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticPlacedFeatures.kt +++ b/src/main/kotlin/dev/hybridlabs/aquatic/world/gen/feature/HybridAquaticPlacedFeatures.kt @@ -15,6 +15,11 @@ object HybridAquaticPlacedFeatures { */ val ANEMONE_PATCH = register("anemone_patch") + /** + * A patch of anemones. + */ + val HYDROTHERMAL_VENTS = register("hydrothermal_vents") + /** * A message in a bottle. */ diff --git a/src/main/resources/assets/hybrid-aquatic/animations/crab_pot.animation.json b/src/main/resources/assets/hybrid-aquatic/animations/crab_pot.animation.json new file mode 100644 index 000000000..2c489d3e3 --- /dev/null +++ b/src/main/resources/assets/hybrid-aquatic/animations/crab_pot.animation.json @@ -0,0 +1,110 @@ +{ + "format_version": "1.8.0", + "animations": { + "water_bob": { + "loop": true, + "animation_length": 4, + "bones": { + "buoy": { + "rotation": { + "0.0": { + "vector": [2.5, 0, 0] + }, + "1.0": { + "vector": [0, 0, 2.5] + }, + "2.0": { + "vector": [-2.5, 0, 0] + }, + "3.0": { + "vector": [0, 0, -2.5] + }, + "4.0": { + "vector": [2.5, 0, 0] + } + }, + "position": { + "0.0": { + "vector": [0, 1, 0] + }, + "2.0": { + "vector": [0, 2, 0] + }, + "4.0": { + "vector": [0, 1, 0] + } + } + }, + "flag": { + "rotation": { + "0.0": { + "vector": [0, 10, 0] + }, + "2.0": { + "vector": [0, -10, 0] + }, + "4.0": { + "vector": [0, 10, 0] + } + } + } + } + }, + "float": { + "loop": true, + "animation_length": 4, + "bones": { + "buoy": { + "rotation": { + "0.0": { + "vector": [2.5, 0, 0] + }, + "1.0": { + "vector": [0, 0, 2.5] + }, + "2.0": { + "vector": [-2.5, 0, 0] + }, + "3.0": { + "vector": [0, 0, -2.5] + }, + "4.0": { + "vector": [2.5, 0, 0] + } + }, + "position": { + "0.0": { + "vector": [0, 1, 0] + }, + "2.0": { + "vector": [0, 2, 0] + }, + "4.0": { + "vector": [0, 1, 0] + } + } + }, + "lantern": { + "rotation": { + "0.0": { + "vector": [-2.5, 0, 0] + }, + "1.0": { + "vector": [0, 0, -2.5] + }, + "2.0": { + "vector": [2.5, 0, 0] + }, + "3.0": { + "vector": [0, 0, 2.5] + }, + "4.0": { + "vector": [-2.5, 0, 0] + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/hybrid-aquatic/animations/hydrothermal_vent.animation.json b/src/main/resources/assets/hybrid-aquatic/animations/hydrothermal_vent.animation.json new file mode 100644 index 000000000..2c489d3e3 --- /dev/null +++ b/src/main/resources/assets/hybrid-aquatic/animations/hydrothermal_vent.animation.json @@ -0,0 +1,110 @@ +{ + "format_version": "1.8.0", + "animations": { + "water_bob": { + "loop": true, + "animation_length": 4, + "bones": { + "buoy": { + "rotation": { + "0.0": { + "vector": [2.5, 0, 0] + }, + "1.0": { + "vector": [0, 0, 2.5] + }, + "2.0": { + "vector": [-2.5, 0, 0] + }, + "3.0": { + "vector": [0, 0, -2.5] + }, + "4.0": { + "vector": [2.5, 0, 0] + } + }, + "position": { + "0.0": { + "vector": [0, 1, 0] + }, + "2.0": { + "vector": [0, 2, 0] + }, + "4.0": { + "vector": [0, 1, 0] + } + } + }, + "flag": { + "rotation": { + "0.0": { + "vector": [0, 10, 0] + }, + "2.0": { + "vector": [0, -10, 0] + }, + "4.0": { + "vector": [0, 10, 0] + } + } + } + } + }, + "float": { + "loop": true, + "animation_length": 4, + "bones": { + "buoy": { + "rotation": { + "0.0": { + "vector": [2.5, 0, 0] + }, + "1.0": { + "vector": [0, 0, 2.5] + }, + "2.0": { + "vector": [-2.5, 0, 0] + }, + "3.0": { + "vector": [0, 0, -2.5] + }, + "4.0": { + "vector": [2.5, 0, 0] + } + }, + "position": { + "0.0": { + "vector": [0, 1, 0] + }, + "2.0": { + "vector": [0, 2, 0] + }, + "4.0": { + "vector": [0, 1, 0] + } + } + }, + "lantern": { + "rotation": { + "0.0": { + "vector": [-2.5, 0, 0] + }, + "1.0": { + "vector": [0, 0, -2.5] + }, + "2.0": { + "vector": [2.5, 0, 0] + }, + "3.0": { + "vector": [0, 0, 2.5] + }, + "4.0": { + "vector": [-2.5, 0, 0] + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/hybrid-aquatic/animations/yeti_crab.animation.json b/src/main/resources/assets/hybrid-aquatic/animations/yeti_crab.animation.json index 7d696a95b..3e486500d 100644 --- a/src/main/resources/assets/hybrid-aquatic/animations/yeti_crab.animation.json +++ b/src/main/resources/assets/hybrid-aquatic/animations/yeti_crab.animation.json @@ -249,6 +249,38 @@ } } } + }, + "idle": { + "loop": true, + "animation_length": 3, + "bones": { + "left_claw": { + "rotation": { + "0.0": { + "vector": [-5, 0, 0] + }, + "1.5": { + "vector": [0, 0, 0] + }, + "3.0": { + "vector": [-5, 0, 0] + } + } + }, + "right_claw": { + "rotation": { + "0.0": { + "vector": [-5, 0, 0] + }, + "1.5": { + "vector": [0, 0, 0] + }, + "3.0": { + "vector": [-5, 0, 0] + } + } + } + } } }, "geckolib_format_version": 2 diff --git a/src/main/resources/assets/hybrid-aquatic/geo/entity/block/hydrothermal_vent.geo.json b/src/main/resources/assets/hybrid-aquatic/geo/entity/block/hydrothermal_vent.geo.json new file mode 100644 index 000000000..54506fc24 --- /dev/null +++ b/src/main/resources/assets/hybrid-aquatic/geo/entity/block/hydrothermal_vent.geo.json @@ -0,0 +1,27 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 2, + "visible_bounds_height": 2.5, + "visible_bounds_offset": [0, 0.75, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [-3, 0, -3], "size": [6, 12, 6], "uv": [0, 0]}, + {"origin": [-4, 0, -6], "size": [4, 8, 4], "uv": [20, 14]}, + {"origin": [3, 0, -1], "size": [3, 6, 3], "uv": [24, 0]}, + {"origin": [-5, 0, 1], "size": [5, 10, 5], "uv": [0, 18]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/hybrid-aquatic/textures/block/hydrothermal_vent.png b/src/main/resources/assets/hybrid-aquatic/textures/block/hydrothermal_vent.png new file mode 100644 index 000000000..8191cf03b Binary files /dev/null and b/src/main/resources/assets/hybrid-aquatic/textures/block/hydrothermal_vent.png differ