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 extends PenguinEggBlock> 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");