Skip to content

Commit

Permalink
Start entity implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
marchermans committed Nov 19, 2023
1 parent fde6cb6 commit c3fc54d
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 84 deletions.
80 changes: 0 additions & 80 deletions src/main/java/net/neoforged/neoforge/network/PlayMessages.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,86 +46,6 @@ public static class SpawnEntity {
private final int velX, velY, velZ;
private final FriendlyByteBuf buf;

SpawnEntity(Entity e) {
this.entity = e;
this.typeId = BuiltInRegistries.ENTITY_TYPE.getId(e.getType()); //TODO: Codecs
this.entityId = e.getId();
this.uuid = e.getUUID();
this.posX = e.getX();
this.posY = e.getY();
this.posZ = e.getZ();
this.pitch = (byte) Mth.floor(e.getXRot() * 256.0F / 360.0F);
this.yaw = (byte) Mth.floor(e.getYRot() * 256.0F / 360.0F);
this.headYaw = (byte) (e.getYHeadRot() * 256.0F / 360.0F);
Vec3 vec3d = e.getDeltaMovement();
double d1 = Mth.clamp(vec3d.x, -3.9D, 3.9D);
double d2 = Mth.clamp(vec3d.y, -3.9D, 3.9D);
double d3 = Mth.clamp(vec3d.z, -3.9D, 3.9D);
this.velX = (int) (d1 * 8000.0D);
this.velY = (int) (d2 * 8000.0D);
this.velZ = (int) (d3 * 8000.0D);
this.buf = null;
}

private SpawnEntity(int typeId, int entityId, UUID uuid, double posX, double posY, double posZ, byte pitch, byte yaw, byte headYaw, int velX, int velY, int velZ, FriendlyByteBuf buf) {
this.entity = null;
this.typeId = typeId;
this.entityId = entityId;
this.uuid = uuid;
this.posX = posX;
this.posY = posY;
this.posZ = posZ;
this.pitch = pitch;
this.yaw = yaw;
this.headYaw = headYaw;
this.velX = velX;
this.velY = velY;
this.velZ = velZ;
this.buf = buf;
}

public static void encode(SpawnEntity msg, FriendlyByteBuf buf) {
buf.writeVarInt(msg.typeId);
buf.writeInt(msg.entityId);
buf.writeLong(msg.uuid.getMostSignificantBits());
buf.writeLong(msg.uuid.getLeastSignificantBits());
buf.writeDouble(msg.posX);
buf.writeDouble(msg.posY);
buf.writeDouble(msg.posZ);
buf.writeByte(msg.pitch);
buf.writeByte(msg.yaw);
buf.writeByte(msg.headYaw);
buf.writeShort(msg.velX);
buf.writeShort(msg.velY);
buf.writeShort(msg.velZ);
if (msg.entity instanceof IEntityAdditionalSpawnData entityAdditionalSpawnData) {
final FriendlyByteBuf spawnDataBuffer = new FriendlyByteBuf(Unpooled.buffer());

entityAdditionalSpawnData.writeSpawnData(spawnDataBuffer);

buf.writeVarInt(spawnDataBuffer.readableBytes());
buf.writeBytes(spawnDataBuffer);

spawnDataBuffer.release();
} else {
buf.writeVarInt(0);
}
}

public static SpawnEntity decode(FriendlyByteBuf buf) {
return new SpawnEntity(buf.readVarInt(), buf.readInt(), new UUID(buf.readLong(), buf.readLong()), buf.readDouble(), buf.readDouble(), buf.readDouble(), buf.readByte(), buf.readByte(), buf.readByte(), buf.readShort(), buf.readShort(), buf.readShort(), readSpawnDataPacket(buf));
}

private static FriendlyByteBuf readSpawnDataPacket(FriendlyByteBuf buf) {
final int count = buf.readVarInt();
if (count > 0) {
final FriendlyByteBuf spawnDataBuffer = new FriendlyByteBuf(Unpooled.buffer());
spawnDataBuffer.writeBytes(buf, count);
return spawnDataBuffer;
}

return new FriendlyByteBuf(Unpooled.buffer());
}

public static boolean handle(SpawnEntity msg, NetworkEvent.Context ctx) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.netty.buffer.Unpooled;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.common.util.LogicalSidedProvider;
import net.neoforged.neoforge.entity.IEntityAdditionalSpawnData;
import net.neoforged.neoforge.network.ConfigSync;
import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
import net.neoforged.neoforge.network.payload.ConfigFilePayload;
import net.neoforged.neoforge.network.payload.FrozenRegistryPayload;
import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletePayload;
import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import net.neoforged.neoforge.network.payload.*;
import net.neoforged.neoforge.registries.ForgeRegistry;
import net.neoforged.neoforge.registries.GameData;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -59,4 +67,32 @@ public void handle(ConfigurationPayloadContext context, FrozenRegistrySyncComple
public void handle(ConfigurationPayloadContext context, ConfigFilePayload payload) {
ConfigSync.INSTANCE.receiveSyncedConfig(payload.contents(), payload.fileName());
}

public void handle(PlayPayloadContext context, AdvancedAddEntityPayload msg) {
EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.byId(msg.typeId());
Optional<Level> world = LogicalSidedProvider.CLIENTWORLD.get(ctx.getDirection().getReceptionSide());
Entity e = world.map(w -> type.customClientSpawn(msg, w)).orElse(null);
if (e == null) {
return;
}

/*
* Sets the postiion on the client, Mirrors what
* Entity#recreateFromPacket and LivingEntity#recreateFromPacket does.
*/
e.syncPacketPositionCodec(msg.posX(), msg.posY(), msg.posZ());
e.absMoveTo(msg.posX(), msg.posY(), msg.posZ(), (msg.yaw() * 360) / 256.0F, (msg.pitch() * 360) / 256.0F);
e.setYHeadRot((msg.headYaw() * 360) / 256.0F);
e.setYBodyRot((msg.headYaw() * 360) / 256.0F);

e.setId(msg.entityId());
e.setUUID(msg.uuid());
world.filter(ClientLevel.class::isInstance).ifPresent(w -> ((ClientLevel) w).addEntity(e));
e.lerpMotion(msg.velX() / 8000.0, msg.velY() / 8000.0, msg.velZ() / 8000.0);
if (e instanceof IEntityAdditionalSpawnData entityAdditionalSpawnData) {
final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(msg.customPayload()));
entityAdditionalSpawnData.readSpawnData(buf);
buf.release();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package net.neoforged.neoforge.network.payload;

import io.netty.buffer.Unpooled;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.entity.IEntityAdditionalSpawnData;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public record AdvancedAddEntityPayload(int typeId,
int entityId,
UUID uuid,
double posX,
double posY,
double posZ,
byte pitch,
byte yaw,
byte headYaw,
int velX,
int velY,
int velZ,
byte[] customPayload) implements CustomPacketPayload {

public static final ResourceLocation ID = new ResourceLocation("neoforge", "advanced_add_entity");

public AdvancedAddEntityPayload(FriendlyByteBuf buf) {
this(
buf.readVarInt(),
buf.readVarInt(),
buf.readUUID(),
buf.readDouble(),
buf.readDouble(),
buf.readDouble(),
buf.readByte(),
buf.readByte(),
buf.readByte(),
buf.readVarInt(),
buf.readVarInt(),
buf.readVarInt(),
buf.readByteArray()
);
}

public AdvancedAddEntityPayload(Entity e) {
this(
BuiltInRegistries.ENTITY_TYPE.getId(e.getType()),
e.getId(),
e.getUUID(),
e.getX(),
e.getY(),
e.getZ(),
(byte) Mth.floor(e.getXRot() * 256.0F / 360.0F),
(byte) Mth.floor(e.getYRot() * 256.0F / 360.0F),
(byte) (e.getYHeadRot() * 256.0F / 360.0F),
(int) (Mth.clamp(e.getDeltaMovement().x, -3.9D, 3.9D) * 8000.0D),
(int) (Mth.clamp(e.getDeltaMovement().y, -3.9D, 3.9D) * 8000.0D),
(int) (Mth.clamp(e.getDeltaMovement().z, -3.9D, 3.9D) * 8000.0D),
writeCustomData(e)
);
}

private static byte[] writeCustomData(final Entity entity) {
final FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());

if (entity instanceof IEntityAdditionalSpawnData additionalSpawnData) {
additionalSpawnData.writeSpawnData(buf);
}

final byte[] payload = buf.array();
buf.release();
return payload;
}

@Override
public void write(@NotNull FriendlyByteBuf buffer) {
buffer.writeVarInt(typeId);
buffer.writeVarInt(entityId);
buffer.writeUUID(uuid);
buffer.writeDouble(posX);
buffer.writeDouble(posY);
buffer.writeDouble(posZ);
buffer.writeByte(pitch);
buffer.writeByte(yaw);
buffer.writeByte(headYaw);
buffer.writeVarInt(velX);
buffer.writeVarInt(velY);
buffer.writeVarInt(velZ);
buffer.writeBytes(customPayload);
}

@Override
public @NotNull ResourceLocation id() {
return ID;
}
}

0 comments on commit c3fc54d

Please sign in to comment.