Skip to content

Commit

Permalink
Merge pull request #106 from doc-bok/104-caterpillars-forgot-how-to-fall
Browse files Browse the repository at this point in the history
[FIX] Caterpillars remember how to fall.
  • Loading branch information
doc-bok committed Feb 16, 2024
2 parents 2282c58 + affd75f commit d2712e0
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 116 deletions.
5 changes: 4 additions & 1 deletion 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)
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Expand Up @@ -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
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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> 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> 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);
}
}
}
}
Expand Down
Expand Up @@ -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.
Expand Down Expand Up @@ -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),
Expand All @@ -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!
*
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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) {
Expand Down
Expand Up @@ -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),
Expand Down
@@ -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;
Expand All @@ -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;

Expand All @@ -38,15 +34,8 @@ public abstract class DirectionalCreature extends Animal {
protected static final EntityDataAccessor<Direction> DATA_DIRECTION =
SynchedEntityData.defineId(DirectionalCreature.class, EntityDataSerializers.DIRECTION);

protected static final EntityDataAccessor<BlockPos> 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;
Expand All @@ -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<? extends Mob> entityType,
LevelAccessor level,
MobSpawnType spawnType,
Expand Down Expand Up @@ -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());
}

/**
Expand All @@ -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,
Expand All @@ -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)) {

Expand All @@ -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();
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -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());
}
}

0 comments on commit d2712e0

Please sign in to comment.