diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e6bd04..30aef03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ ## Changelog -### 3.0.1 (2024-02-15) +### 3.0.2 (2024-02-16) +- Caterpillars remembered how to fall. + +### 3.0.1 (2024-02-16) - Fixed Butterfly Data not being synced with clients correctly. ### 3.0.0 (2024-02-15) diff --git a/gradle.properties b/gradle.properties index 2ef72d7..2f3f893 100644 --- a/gradle.properties +++ b/gradle.properties @@ -48,7 +48,7 @@ mod_name=Butterfly Mod # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=All Rights Reserved # The mod version. See https://semver.org/ -mod_version=3.0.1 +mod_version=3.0.2 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/com/bokmcdok/butterflies/event/network/NetworkEventListener.java b/src/main/java/com/bokmcdok/butterflies/event/network/NetworkEventListener.java index 840b5ca..197ffb7 100644 --- a/src/main/java/com/bokmcdok/butterflies/event/network/NetworkEventListener.java +++ b/src/main/java/com/bokmcdok/butterflies/event/network/NetworkEventListener.java @@ -3,6 +3,7 @@ import com.bokmcdok.butterflies.ButterfliesMod; import com.bokmcdok.butterflies.network.protocol.common.custom.ClientboundButterflyDataPacket; import com.bokmcdok.butterflies.world.ButterflyData; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; import net.minecraft.server.level.ServerPlayer; @@ -62,21 +63,23 @@ public static void onCustomPayload(CustomPayloadEvent event) { if (event.getChannel().compareTo(ClientboundButterflyDataPacket.ID) == 0) { // Extract the data from the payload. - List butterflyData = event.getPayload().readCollection(ArrayList::new, (buffer) -> { - return new ButterflyData(buffer.readInt(), - buffer.readUtf(), - buffer.readEnum(ButterflyData.Size.class), - buffer.readEnum(ButterflyData.Speed.class), - buffer.readEnum(ButterflyData.Rarity.class), - buffer.readEnum(ButterflyData.Habitat.class), - buffer.readInt(), - buffer.readInt(), - buffer.readInt()); - }); + FriendlyByteBuf payload = event.getPayload(); + if (payload != null) { + List butterflyData = payload.readCollection(ArrayList::new, + (buffer) -> new ButterflyData(buffer.readInt(), + buffer.readUtf(), + buffer.readEnum(ButterflyData.Size.class), + buffer.readEnum(ButterflyData.Speed.class), + buffer.readEnum(ButterflyData.Rarity.class), + buffer.readEnum(ButterflyData.Habitat.class), + buffer.readInt(), + buffer.readInt(), + buffer.readInt())); - // Register the new data. - for (ButterflyData butterfly : butterflyData) { - ButterflyData.addButterfly(butterfly); + // Register the new data. + for (ButterflyData butterfly : butterflyData) { + ButterflyData.addButterfly(butterfly); + } } } } diff --git a/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Caterpillar.java b/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Caterpillar.java index eac98ee..03ea685 100644 --- a/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Caterpillar.java +++ b/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Caterpillar.java @@ -66,7 +66,7 @@ public class Caterpillar extends DirectionalCreature { @Nullable private Vec3 targetPosition; - // Whether or not gravity is being applied. + // Whether gravity is being applied. private boolean isNoGravity = true; // The size of the caterpillar. @@ -324,47 +324,25 @@ public static void spawn(ServerLevel level, double y = position.getY() + 0.4D; double z = position.getZ() + 0.5D; - BlockPos spawnPosition = position.above(); - if (isBottled) { direction = Direction.DOWN; y = Math.floor(position.getY()) + 0.07d; - spawnPosition = position.below(); caterpillar.setInvulnerable(true); caterpillar.setPersistenceRequired(); } else { switch (direction) { - case DOWN -> { - y = Math.floor(position.getY()); - spawnPosition = position.below(); - } - case UP -> { - y = Math.floor(position.getY()) + 1.0d; - spawnPosition = position.above(); - } - case NORTH -> { - z = Math.floor(position.getZ()); - spawnPosition = position.north(); - } - case SOUTH -> { - z = Math.floor(position.getZ()) + 1.0d; - spawnPosition = position.south(); - } - case WEST -> { - x = Math.floor(position.getX()); - spawnPosition = position.west(); - } - case EAST -> { - x = Math.floor(position.getX()) + 1.0d; - spawnPosition = position.east(); - } + case DOWN -> y = Math.floor(position.getY()); + case UP -> y = Math.floor(position.getY()) + 1.0d; + case NORTH -> z = Math.floor(position.getZ()); + case SOUTH -> z = Math.floor(position.getZ()) + 1.0d; + case WEST -> x = Math.floor(position.getX()); + case EAST -> x = Math.floor(position.getX()) + 1.0d; } } caterpillar.moveTo(x, y, z, 0.0F, 0.0F); caterpillar.setSurfaceDirection(direction); - caterpillar.setSurfaceBlockPos(spawnPosition); caterpillar.finalizeSpawn(level, level.getCurrentDifficultyAt(position), @@ -387,7 +365,6 @@ public void addAdditionalSaveData(@NotNull CompoundTag tag) { tag.putBoolean(IS_BOTTLED, this.entityData.get(DATA_IS_BOTTLED)); } - /** * Reduce the size of the caterpillar - they are small! * @@ -527,19 +504,35 @@ protected Caterpillar(String species, * A custom step for the AI update loop. */ @Override + @SuppressWarnings("deprecation") protected void customServerAiStep() { super.customServerAiStep(); // Update gravity isNoGravity = true; - if (!this.getIsBottled() - && this.level().hasChunkAt(getSurfaceBlockPos()) - && this.level().isEmptyBlock(getSurfaceBlockPos())) { - setSurfaceDirection(Direction.DOWN); - setSurfaceBlockPos(this.blockPosition().below()); - this.targetPosition = null; - isNoGravity = false; + if (this.getIsReleased()) { + BlockPos surfaceBlockPos = this.getSurfaceBlockPos(); + if (this.level().hasChunkAt(surfaceBlockPos)) { + + // If the surface block is empty then we try to look for one below. + if (this.level().isEmptyBlock(surfaceBlockPos)) { + setSurfaceDirection(Direction.DOWN); + } + + // Caterpillars will only fall if their surface direction is + // down. + if (getSurfaceDirection() == Direction.DOWN) { + + // If the surface block is still empty, or the caterpillar is + // too far above the surface block, then it should fall. + if (this.level().isEmptyBlock(surfaceBlockPos) + || this.position().y() - (double) this.blockPosition().getY() > 0.01) { + this.targetPosition = null; + isNoGravity = false; + } + } + } } // If the caterpillar is falling then it can't crawl. @@ -665,7 +658,7 @@ protected void customServerAiStep() { this.setYRot(this.getYRot() + (float) rotationDelta); // Spawn Chrysalis. - if (!this.getIsBottled() + if (this.getIsReleased() && this.getAge() >= 0 && this.random.nextInt(0, 15) == 0) { BlockPos surfaceBlockPos = this.getSurfaceBlockPos(); @@ -712,11 +705,11 @@ protected void doPush(@NotNull Entity otherEntity) { /** * Check if the caterpillar is in a bottle or not. - * @return TRUE if the caterpillar is in a bottle. + * @return TRUE if the caterpillar is free. */ @Override - protected boolean getIsBottled() { - return entityData.get(DATA_IS_BOTTLED); + protected boolean getIsReleased() { + return !entityData.get(DATA_IS_BOTTLED); } /** @@ -761,7 +754,7 @@ protected void pushEntities() { } /** - * Set whether or not the caterpillar is in a bottle. + * Set whether the caterpillar is in a bottle. * @param isBottled TRUE if the caterpillar is bottled. */ private void setIsBottled(boolean isBottled) { diff --git a/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Chrysalis.java b/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Chrysalis.java index 92fd543..51d35f7 100644 --- a/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Chrysalis.java +++ b/src/main/java/com/bokmcdok/butterflies/world/entity/animal/Chrysalis.java @@ -270,7 +270,6 @@ public static void spawn(ServerLevel level, chrysalis.moveTo(position.x, position.y, position.z, 0.0F, 0.0F); chrysalis.setYRot(yRotation); chrysalis.setSurfaceDirection(surfaceDirection); - chrysalis.setSurfaceBlockPos(spawnBlock); chrysalis.finalizeSpawn(level, level.getCurrentDifficultyAt(spawnBlock), diff --git a/src/main/java/com/bokmcdok/butterflies/world/entity/animal/DirectionalCreature.java b/src/main/java/com/bokmcdok/butterflies/world/entity/animal/DirectionalCreature.java index ee17c03..c644926 100644 --- a/src/main/java/com/bokmcdok/butterflies/world/entity/animal/DirectionalCreature.java +++ b/src/main/java/com/bokmcdok/butterflies/world/entity/animal/DirectionalCreature.java @@ -1,7 +1,6 @@ package com.bokmcdok.butterflies.world.entity.animal; import com.bokmcdok.butterflies.ButterfliesMod; -import com.mojang.logging.LogUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -24,11 +23,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; import javax.annotation.Nullable; @@ -38,15 +34,8 @@ public abstract class DirectionalCreature extends Animal { protected static final EntityDataAccessor DATA_DIRECTION = SynchedEntityData.defineId(DirectionalCreature.class, EntityDataSerializers.DIRECTION); - protected static final EntityDataAccessor DATA_SURFACE_BLOCK = - SynchedEntityData.defineId(DirectionalCreature.class, EntityDataSerializers.BLOCK_POS); - // Names of the attributes stored in the save data. protected static final String DIRECTION = "direction"; - protected static final String SURFACE_BLOCK = "surface_block"; - - // Directly reference a slf4j logger - private static final Logger LOGGER = LogUtils.getLogger(); // The location of the texture that the renderer should use. private final ResourceLocation texture; @@ -60,6 +49,7 @@ public abstract class DirectionalCreature extends Animal { * @param random A random source. * @return TRUE if there is a leaf block nearby. */ + @SuppressWarnings("deprecation, unused") public static boolean checkDirectionalSpawnRules(EntityType entityType, LevelAccessor level, MobSpawnType spawnType, @@ -94,7 +84,6 @@ public static AttributeSupplier.Builder createAttributes() { public void addAdditionalSaveData(@NotNull CompoundTag tag) { super.addAdditionalSaveData(tag); tag.putString(DIRECTION, this.entityData.get(DATA_DIRECTION).getName()); - tag.putString(SURFACE_BLOCK, this.entityData.get(DATA_SURFACE_BLOCK).toShortString()); } /** @@ -108,6 +97,7 @@ public void addAdditionalSaveData(@NotNull CompoundTag tag) { * @return The updated group data. */ @Override + @SuppressWarnings("deprecation") public SpawnGroupData finalizeSpawn(@NotNull ServerLevelAccessor levelAccessor, @NotNull DifficultyInstance difficulty, @NotNull MobSpawnType spawnType, @@ -118,11 +108,10 @@ public SpawnGroupData finalizeSpawn(@NotNull ServerLevelAccessor levelAccessor, } if (!levelAccessor.hasChunkAt(getSurfaceBlockPos())) { - this.setSurfaceBlockPos(this.blockPosition().below()); this.setSurfaceDirection(Direction.DOWN); } - if (!getIsBottled()) { + if (getIsReleased()) { if (levelAccessor.hasChunkAt(getSurfaceBlockPos()) && !levelAccessor.getBlockState(getSurfaceBlockPos()).is(BlockTags.LEAVES)) { @@ -132,7 +121,6 @@ public SpawnGroupData finalizeSpawn(@NotNull ServerLevelAccessor levelAccessor, levelAccessor.getBlockState(surfacePosition).is(BlockTags.LEAVES)) { this.setSurfaceDirection(direction); - this.setSurfaceBlockPos(surfacePosition); Vec3 position = this.position(); double x = position.x(); @@ -197,25 +185,6 @@ public void readAdditionalSaveData(@NotNull CompoundTag tag) { this.entityData.set(DATA_DIRECTION, direction); } } - - // Get the surface block - if (tag.contains(SURFACE_BLOCK)) { - String data = tag.getString(SURFACE_BLOCK); - String[] values = data.split(","); - BlockPos position = new BlockPos( - Integer.parseInt(values[0].trim()), - Integer.parseInt(values[1].trim()), - Integer.parseInt(values[2].trim())); - this.entityData.set(DATA_SURFACE_BLOCK, position); - } - } - - /** - * Set the position of the block the caterpillar is crawling on. - * @param position The position of the block. - */ - public void setSurfaceBlockPos(BlockPos position) { - this.entityData.set(DATA_SURFACE_BLOCK, position); } /** @@ -252,15 +221,14 @@ protected DirectionalCreature(String texture, protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_DIRECTION, Direction.DOWN); - this.entityData.define(DATA_SURFACE_BLOCK, new BlockPos(0,0,0)); } /** - * Check if the caterpillar is in a bottle or not. - * @return TRUE if the caterpillar is in a bottle. + * Check if the entity is free to move around. + * @return TRUE if the entity is free. */ - protected boolean getIsBottled() { - return false; + protected boolean getIsReleased() { + return true; } /** @@ -271,28 +239,11 @@ public ResourceLocation getTexture() { return texture; } - /** - * Get the block the caterpillar is crawling on. - * @return The position of the block. - */ - protected Block getSurfaceBlock() { - return getSurfaceBlockState().getBlock(); - } - /** * Get the position of the block the caterpillar is crawling on. * @return The position of the block. */ protected BlockPos getSurfaceBlockPos() { - return this.entityData.get(DATA_SURFACE_BLOCK); - } - - /** - * Get the block the caterpillar is crawling on. - * @return The position of the block. - */ - protected BlockState getSurfaceBlockState() { - BlockPos position = getSurfaceBlockPos(); - return this.level().getBlockState(position); + return this.blockPosition().relative(this.getSurfaceDirection()); } }