From 3300c7cd56d15c7d2e0c9bed744efed9c3c8836c Mon Sep 17 00:00:00 2001 From: AViewFromTheTop <87103914+AViewFromTheTop@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:14:55 -0500 Subject: [PATCH] penguin egg --- .../wilderwild/block/PenguinEggBlock.java | 139 ++++++++++++++++++ .../datagen/tag/WWEntityTagProvider.java | 4 + .../wilderwild/registry/WWBlocks.java | 11 ++ .../wilderwild/tag/WWEntityTags.java | 1 + 4 files changed, 155 insertions(+) create mode 100644 src/main/java/net/frozenblock/wilderwild/block/PenguinEggBlock.java diff --git a/src/main/java/net/frozenblock/wilderwild/block/PenguinEggBlock.java b/src/main/java/net/frozenblock/wilderwild/block/PenguinEggBlock.java new file mode 100644 index 000000000..7ac6e8f49 --- /dev/null +++ b/src/main/java/net/frozenblock/wilderwild/block/PenguinEggBlock.java @@ -0,0 +1,139 @@ +/* + * Copyright 2023-2025 FrozenBlock + * This file is part of Wilder Wild. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +package net.frozenblock.wilderwild.block; + +import com.mojang.serialization.MapCodec; +import net.frozenblock.wilderwild.entity.Penguin; +import net.frozenblock.wilderwild.registry.WWEntityTypes; +import net.frozenblock.wilderwild.registry.WWSounds; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LevelEvent; +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.IntegerProperty; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; + +public class PenguinEggBlock extends Block { + public static final int MAX_HATCH_LEVEL = 2; + public static final IntegerProperty HATCH = BlockStateProperties.HATCH; + public static final MapCodec CODEC = simpleCodec(PenguinEggBlock::new); + private static final VoxelShape SHAPE = Block.box(5D, 0D, 5D, 11D, 8D, 11D); + + public PenguinEggBlock(Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(HATCH, 0)); + } + + public static boolean isSafeToHatch(@NotNull Level level, @NotNull BlockPos belowPos) { + return level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP); + } + + @NotNull + @Override + protected MapCodec codec() { + return CODEC; + } + + @Override + public void createBlockStateDefinition(StateDefinition.@NotNull Builder builder) { + builder.add(HATCH); + } + + @NotNull + @Override + public VoxelShape getShape(@NotNull BlockState state, @NotNull BlockGetter level, @NotNull BlockPos pos, @NotNull CollisionContext context) { + return SHAPE; + } + + public int getHatchLevel(@NotNull BlockState state) { + return state.getValue(HATCH); + } + + private boolean isReadyToHatch(BlockState state) { + return this.getHatchLevel(state) == MAX_HATCH_LEVEL; + } + + @Override + public void randomTick(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos pos, @NotNull RandomSource random) { + if (shouldUpdateHatchLevel(level, pos)) { + if (!this.isReadyToHatch(state)) { + level.playSound(null, pos, WWSounds.BLOCK_OSTRICH_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + level.setBlock(pos, state.cycle(HATCH), UPDATE_CLIENTS); + } else { + this.hatchPenguinEgg(level, pos, random); + } + } + } + + @Override + public void onPlace(@NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos, @NotNull BlockState oldState, boolean movedByPiston) { + super.onPlace(state, level, pos, oldState, movedByPiston); + level.levelEvent(LevelEvent.PARTICLES_EGG_CRACK, pos, 0); + } + + private boolean shouldUpdateHatchLevel(@NotNull Level level, @NotNull BlockPos blockPos) { + if (!isSafeToHatch(level, blockPos.below())) return false; + if (level.isDay()) { + return true; + } else { + return level.getRandom().nextInt(500) == 0; + } + } + + private void hatchPenguinEgg(@NotNull ServerLevel level, BlockPos pos, @NotNull RandomSource random) { + level.playSound(null, pos, WWSounds.BLOCK_OSTRICH_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + this.destroyBlock(level, pos); + this.spawnPenguin(level, pos, random); + } + + private void destroyBlock(@NotNull Level level, BlockPos pos) { + level.destroyBlock(pos, false); + } + + private void spawnPenguin(ServerLevel level, BlockPos pos, @NotNull RandomSource random) { + Penguin penguin = WWEntityTypes.PENGUIN.create(level); + if (penguin != null) { + penguin.setBaby(true); + penguin.moveTo( + pos.getX() + 0.5D, + pos.getY(), + pos.getZ() + 0.5D, + random.nextInt(1, 361), + 0F + ); + level.addFreshEntity(penguin); + } + } + + @Override + public boolean isPathfindable(@NotNull BlockState state, @NotNull PathComputationType type) { + return false; + } +} diff --git a/src/main/java/net/frozenblock/wilderwild/datagen/tag/WWEntityTagProvider.java b/src/main/java/net/frozenblock/wilderwild/datagen/tag/WWEntityTagProvider.java index 7a8edb85f..8a1c168f0 100644 --- a/src/main/java/net/frozenblock/wilderwild/datagen/tag/WWEntityTagProvider.java +++ b/src/main/java/net/frozenblock/wilderwild/datagen/tag/WWEntityTagProvider.java @@ -115,6 +115,10 @@ protected void addTags(@NotNull HolderLookup.Provider arg) { .add(EntityType.TROPICAL_FISH) .add(EntityType.TADPOLE); + this.getOrCreateTagBuilder(WWEntityTags.PENGUIN_HUNT_TARGETS) + .add(EntityType.SQUID) + .add(EntityType.GLOW_SQUID); + this.getOrCreateTagBuilder(WWEntityTags.GEYSER_PUSHES_FURTHER) .add(EntityType.ARROW) .add(EntityType.SPECTRAL_ARROW); diff --git a/src/main/java/net/frozenblock/wilderwild/registry/WWBlocks.java b/src/main/java/net/frozenblock/wilderwild/registry/WWBlocks.java index 88f19c033..863510253 100644 --- a/src/main/java/net/frozenblock/wilderwild/registry/WWBlocks.java +++ b/src/main/java/net/frozenblock/wilderwild/registry/WWBlocks.java @@ -58,6 +58,7 @@ import net.frozenblock.wilderwild.block.OsseousSculkBlock; import net.frozenblock.wilderwild.block.OstrichEggBlock; import net.frozenblock.wilderwild.block.PalmFrondsBlock; +import net.frozenblock.wilderwild.block.PenguinEggBlock; import net.frozenblock.wilderwild.block.PollenBlock; import net.frozenblock.wilderwild.block.PricklyPearCactusBlock; import net.frozenblock.wilderwild.block.ScorchedBlock; @@ -560,6 +561,15 @@ public final class WWBlocks { .randomTicks() ); + public static final PenguinEggBlock PENGUIN_EGG = new PenguinEggBlock( + BlockBehaviour.Properties.of() + .mapColor(MapColor.TERRACOTTA_WHITE) + .strength(0.5F) + .sound(SoundType.METAL) + .noOcclusion() + .randomTicks() + ); + public static final Block NULL_BLOCK = new Block( BlockBehaviour.Properties.ofFullCopy(Blocks.STONE) .sound(WWSoundTypes.NULL_BLOCK) @@ -1183,6 +1193,7 @@ public static void registerNotSoPlants() { Registry.register(BuiltInRegistries.BLOCK, WWConstants.id("flowering_lily_pad"), FLOWERING_LILY_PAD); registerBlockAfter(Items.WET_SPONGE, "sponge_bud", SPONGE_BUD, CreativeModeTabs.NATURAL_BLOCKS); registerBlockBefore(Items.SNIFFER_EGG, "ostrich_egg", OSTRICH_EGG, CreativeModeTabs.NATURAL_BLOCKS); + registerBlockAfter(OSTRICH_EGG, "penguin_egg", PENGUIN_EGG, CreativeModeTabs.NATURAL_BLOCKS); } public static void registerMisc() { diff --git a/src/main/java/net/frozenblock/wilderwild/tag/WWEntityTags.java b/src/main/java/net/frozenblock/wilderwild/tag/WWEntityTags.java index c4e81f60c..8ecad156d 100644 --- a/src/main/java/net/frozenblock/wilderwild/tag/WWEntityTags.java +++ b/src/main/java/net/frozenblock/wilderwild/tag/WWEntityTags.java @@ -30,6 +30,7 @@ public final class WWEntityTags { public static final TagKey> ANCIENT_HORN_IMMUNE = bind("ancient_horn_immune"); public static final TagKey> JELLYFISH_CANT_STING = bind("jellyfish_cant_sting"); public static final TagKey> CRAB_HUNT_TARGETS = bind("crab_hunt_targets"); + public static final TagKey> PENGUIN_HUNT_TARGETS = bind("penguin_hunt_targets"); public static final TagKey> COCONUT_CANT_BONK = bind("coconut_cant_bonk"); public static final TagKey> COCONUT_CANT_SPLIT = bind("coconut_cant_split"); public static final TagKey> TUMBLEWEED_PASSES_THROUGH = bind("tumbleweed_passes_through");