mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
Entity SNBT Support and Cleanup
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
package com.dfsek.terra.api.block;
|
||||
|
||||
import com.dfsek.terra.api.Handle;
|
||||
|
||||
|
||||
public interface BlockData extends Handle {
|
||||
String toString();
|
||||
}
|
||||
@@ -12,12 +12,13 @@ import java.util.function.Consumer;
|
||||
import com.dfsek.terra.api.Handle;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.state.properties.Property;
|
||||
import com.dfsek.terra.api.data.Extendable;
|
||||
|
||||
|
||||
/**
|
||||
* Contains basic data about a {@link BlockType} in the world
|
||||
*/
|
||||
public interface BlockState extends Handle {
|
||||
public interface BlockState extends Handle, Extendable {
|
||||
|
||||
/**
|
||||
* Whether this {@link BlockState} matches another.
|
||||
@@ -115,12 +116,4 @@ public interface BlockState extends Handle {
|
||||
* @return Whether this state is air
|
||||
*/
|
||||
boolean isAir();
|
||||
|
||||
/**
|
||||
* Get whether this BlockState is an extended state.
|
||||
* Extended states are states that contain extra data not normally present in a BlockState.
|
||||
*
|
||||
* @return Whether this state is extended.
|
||||
*/
|
||||
default boolean isExtended() { return false; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.api.block.state;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockData;
|
||||
import com.dfsek.terra.api.data.ExtendedData;
|
||||
|
||||
|
||||
public interface BlockStateExtended extends BlockState {
|
||||
@@ -9,7 +9,7 @@ public interface BlockStateExtended extends BlockState {
|
||||
*
|
||||
* @return BlockData of this BlockStateExtended
|
||||
*/
|
||||
BlockData getData();
|
||||
ExtendedData getData();
|
||||
|
||||
/**
|
||||
* Sets the BlockData.
|
||||
@@ -18,7 +18,7 @@ public interface BlockStateExtended extends BlockState {
|
||||
*
|
||||
* @return New BlockStateExtended with the given BlockData
|
||||
*/
|
||||
BlockStateExtended setData(BlockData data);
|
||||
BlockStateExtended setData(ExtendedData data);
|
||||
|
||||
/**
|
||||
* Gets the BlockState.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.dfsek.terra.api.data;
|
||||
|
||||
public interface Extendable {
|
||||
/**
|
||||
* Get whether this BlockState is an extended state.
|
||||
* Extended states are states that contain extra data not normally present in a BlockState.
|
||||
*
|
||||
* @return Whether this state is extended.
|
||||
*/
|
||||
default boolean isExtended() { return false; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.api.data;
|
||||
|
||||
import com.dfsek.terra.api.Handle;
|
||||
|
||||
|
||||
public interface ExtendedData extends Handle {
|
||||
String toString();
|
||||
}
|
||||
@@ -8,7 +8,8 @@
|
||||
package com.dfsek.terra.api.entity;
|
||||
|
||||
import com.dfsek.terra.api.Handle;
|
||||
import com.dfsek.terra.api.data.Extendable;
|
||||
|
||||
|
||||
public interface EntityType extends Handle {
|
||||
public interface EntityType extends Handle, Extendable {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.api.entity;
|
||||
|
||||
import com.dfsek.terra.api.data.ExtendedData;
|
||||
|
||||
|
||||
public interface EntityTypeExtended extends EntityType {
|
||||
/**
|
||||
* Gets the BlockData.
|
||||
*
|
||||
* @return BlockData of this EntityTypeExtended
|
||||
*/
|
||||
ExtendedData getData();
|
||||
|
||||
/**
|
||||
* Sets the BlockData.
|
||||
*
|
||||
* @param data BlockData to set
|
||||
*
|
||||
* @return New EntityTypeExtended with the given BlockData
|
||||
*/
|
||||
EntityTypeExtended setData(ExtendedData data);
|
||||
|
||||
/**
|
||||
* Gets the EntityType.
|
||||
*
|
||||
* @return Raw EntityType of this EntityTypeExtended
|
||||
*/
|
||||
EntityType getType();
|
||||
|
||||
@Override
|
||||
default boolean isExtended() { return true; }
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package com.dfsek.terra.mod.handle;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.Blocks;
|
||||
@@ -25,7 +26,11 @@ import net.minecraft.command.argument.BlockArgumentParser;
|
||||
import net.minecraft.command.argument.BlockArgumentParser.BlockResult;
|
||||
import net.minecraft.command.argument.BlockStateArgument;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.StringNbtReader;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.entry.RegistryEntry.Reference;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,6 +41,9 @@ import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.state.BlockStateExtended;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.handle.WorldHandle;
|
||||
import com.dfsek.terra.mod.implmentation.FabricEntityTypeExtended;
|
||||
|
||||
import static net.minecraft.command.argument.BlockArgumentParser.INVALID_BLOCK_ID_EXCEPTION;
|
||||
|
||||
|
||||
public class MinecraftWorldHandle implements WorldHandle {
|
||||
@@ -45,6 +53,7 @@ public class MinecraftWorldHandle implements WorldHandle {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MinecraftWorldHandle.class);
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@Override
|
||||
public @NotNull BlockState createBlockState(@NotNull String data) {
|
||||
try {
|
||||
@@ -61,8 +70,12 @@ public class MinecraftWorldHandle implements WorldHandle {
|
||||
nbtCompound.putInt("z", 0);
|
||||
|
||||
nbtCompound.put("id", BlockEntity.TYPE_CODEC, blockEntity.getType());
|
||||
}
|
||||
|
||||
blockState = (BlockStateExtended) new BlockStateArgument(state, blockResult.properties().keySet(), nbtCompound);
|
||||
} else {
|
||||
blockState = (BlockState) state;
|
||||
}
|
||||
|
||||
} else {
|
||||
blockState = (BlockState) blockResult.blockState();
|
||||
}
|
||||
@@ -80,10 +93,39 @@ public class MinecraftWorldHandle implements WorldHandle {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull EntityType getEntity(@NotNull String id) {
|
||||
if(!id.contains(":")) throw new IllegalArgumentException("Invalid entity identifier " + id);
|
||||
Identifier identifier = Identifier.tryParse(id);
|
||||
if(identifier == null) identifier = Identifier.tryParse(id);
|
||||
return (EntityType) Registries.ENTITY_TYPE.getEntry(identifier).orElseThrow().value();
|
||||
public @NotNull EntityType getEntity(@NotNull String data) {
|
||||
try {
|
||||
Identifier identifier;
|
||||
NbtCompound nbtData = null;
|
||||
StringReader reader = new StringReader(data);
|
||||
|
||||
int i = reader.getCursor();
|
||||
|
||||
identifier = Identifier.fromCommandInput(reader);
|
||||
|
||||
net.minecraft.entity.EntityType<?> entity =
|
||||
(net.minecraft.entity.EntityType<?>) ((Reference<?>) Registries.ENTITY_TYPE.getOptional(
|
||||
RegistryKey.of(RegistryKeys.ENTITY_TYPE, identifier)).orElseThrow(() -> {
|
||||
reader.setCursor(i);
|
||||
return INVALID_BLOCK_ID_EXCEPTION.createWithContext(reader, identifier.toString());
|
||||
})).value();
|
||||
|
||||
if(reader.canRead() && reader.peek() == '{') {
|
||||
nbtData = StringNbtReader.readCompoundAsArgument(reader);
|
||||
nbtData.putString("id", entity.getRegistryEntry().registryKey().getValue().toString());
|
||||
}
|
||||
|
||||
EntityType entityType;
|
||||
if(nbtData != null) {
|
||||
entityType = new FabricEntityTypeExtended(entity, nbtData);
|
||||
} else {
|
||||
entityType = (EntityType) entity;
|
||||
}
|
||||
|
||||
if(identifier == null) throw new IllegalArgumentException("Invalid data: " + data);
|
||||
return entityType;
|
||||
} catch(CommandSyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.dfsek.terra.mod.implmentation;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
||||
import com.dfsek.terra.api.data.ExtendedData;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.api.entity.EntityTypeExtended;
|
||||
|
||||
|
||||
public record FabricEntityTypeExtended(net.minecraft.entity.EntityType<?> entityType, NbtCompound nbtCompound)
|
||||
implements EntityTypeExtended {
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@Override
|
||||
public ExtendedData getData() {
|
||||
return (ExtendedData) ((Object) nbtCompound);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@Override
|
||||
public EntityTypeExtended setData(ExtendedData data) {
|
||||
return new FabricEntityTypeExtended(entityType, data.getClass().equals(NbtCompound.class) ? ((NbtCompound) ((Object) data)) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getType() {
|
||||
return (EntityType) entityType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return entityType;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import com.dfsek.terra.api.block.entity.MobSpawner;
|
||||
import com.dfsek.terra.api.block.entity.SerialState;
|
||||
import com.dfsek.terra.api.entity.EntityType;
|
||||
import com.dfsek.terra.mod.CommonPlatform;
|
||||
import com.dfsek.terra.mod.implmentation.FabricEntityTypeExtended;
|
||||
import com.dfsek.terra.mod.mixin.access.MobSpawnerLogicAccessor;
|
||||
|
||||
|
||||
@@ -66,7 +67,10 @@ public abstract class MobSpawnerBlockEntityMixin extends BlockEntity {
|
||||
} else {
|
||||
rand = Random.create();
|
||||
}
|
||||
setEntityType((net.minecraft.entity.EntityType<?>) creatureType, rand);
|
||||
net.minecraft.entity.EntityType<?> entityType =
|
||||
(((net.minecraft.entity.EntityType<?>) (creatureType.isExtended() && creatureType.getClass().equals(
|
||||
FabricEntityTypeExtended.class) ? ((FabricEntityTypeExtended) creatureType).getType() : creatureType)));
|
||||
setEntityType(entityType, rand);
|
||||
}
|
||||
|
||||
public int terra$getDelay() {
|
||||
|
||||
@@ -15,10 +15,10 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockData;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.state.BlockStateExtended;
|
||||
import com.dfsek.terra.api.block.state.properties.Property;
|
||||
import com.dfsek.terra.api.data.ExtendedData;
|
||||
|
||||
|
||||
@Mixin(BlockStateArgument.class)
|
||||
@@ -72,19 +72,23 @@ public abstract class BlockStateArgumentMixin implements Predicate<CachedBlockPo
|
||||
|
||||
@SuppressWarnings({ "ConstantValue", "DataFlowIssue", "EqualsBetweenInconvertibleTypes" })
|
||||
@Intrinsic
|
||||
public BlockStateExtended terra$setData(BlockData data) {
|
||||
public BlockStateExtended terra$setData(ExtendedData data) {
|
||||
return (BlockStateExtended) new BlockStateArgument(getBlockState(), getProperties(),
|
||||
data.getClass().equals(NbtCompound.class) ? ((NbtCompound) ((Object) data)) : null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@Intrinsic
|
||||
public BlockData terra$getData() {
|
||||
return ((BlockData) ((Object) data));
|
||||
public ExtendedData terra$getData() {
|
||||
return ((ExtendedData) ((Object) data));
|
||||
}
|
||||
|
||||
@Intrinsic
|
||||
public com.dfsek.terra.api.block.state.BlockState terra$getState() {
|
||||
return (com.dfsek.terra.api.block.state.BlockState) getBlockState();
|
||||
}
|
||||
|
||||
public Object terra$getHandle() {
|
||||
return getBlockState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ import org.spongepowered.asm.mixin.Interface;
|
||||
import org.spongepowered.asm.mixin.Intrinsic;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockData;
|
||||
import com.dfsek.terra.api.data.ExtendedData;
|
||||
|
||||
|
||||
@Mixin(NbtCompound.class)
|
||||
@Implements(@Interface(iface = BlockData.class, prefix = "terra$"))
|
||||
@Implements(@Interface(iface = ExtendedData.class, prefix = "terra$"))
|
||||
public abstract class NbtCompoundMixin implements NbtElement {
|
||||
@Intrinsic
|
||||
public String terra$toString() {
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
|
||||
import com.dfsek.terra.mod.implmentation.FabricEntityTypeExtended;
|
||||
import com.dfsek.terra.mod.util.MinecraftUtil;
|
||||
|
||||
|
||||
@@ -162,10 +163,24 @@ public abstract class ChunkRegionMixin implements StructureWorldAccess {
|
||||
return terra$config.getBiomeProvider();
|
||||
}
|
||||
|
||||
public Entity terraWorld$spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType<?>) entityType).create(world, SpawnReason.CHUNK_GENERATION);
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public Entity terraWorld$spawnEntity(double x, double y, double z, EntityType data) {
|
||||
boolean isExtended = data.isExtended() && data.getClass().equals(FabricEntityTypeExtended.class);
|
||||
net.minecraft.entity.Entity entity;
|
||||
if(isExtended) {
|
||||
FabricEntityTypeExtended type = ((FabricEntityTypeExtended) data);
|
||||
NbtCompound nbt = (NbtCompound) ((Object) type.getData());
|
||||
entity = net.minecraft.entity.EntityType.loadEntityWithPassengers(nbt, world, SpawnReason.CHUNK_GENERATION, (entityx) -> {
|
||||
entityx.refreshPositionAndAngles(x, y, z, entityx.getYaw(), entityx.getPitch());
|
||||
return entityx;
|
||||
});
|
||||
spawnEntity(entity);
|
||||
} else {
|
||||
entity = ((net.minecraft.entity.EntityType<?>) data).create(world, SpawnReason.CHUNK_GENERATION);
|
||||
entity.setPos(x, y, z);
|
||||
spawnEntity(entity);
|
||||
}
|
||||
|
||||
return (Entity) entity;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.dfsek.terra.api.world.chunk.Chunk;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
|
||||
import com.dfsek.terra.mod.generation.TerraBiomeSource;
|
||||
import com.dfsek.terra.mod.implmentation.FabricEntityTypeExtended;
|
||||
import com.dfsek.terra.mod.util.MinecraftUtil;
|
||||
|
||||
|
||||
@@ -69,10 +70,23 @@ public abstract class ServerWorldMixin extends World {
|
||||
public abstract WorldTickScheduler<Fluid> getFluidTickScheduler();
|
||||
|
||||
|
||||
public Entity terra$spawnEntity(double x, double y, double z, EntityType entityType) {
|
||||
net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType<?>) entityType).create(null, SpawnReason.CHUNK_GENERATION);
|
||||
public Entity terra$spawnEntity(double x, double y, double z, EntityType data) {
|
||||
boolean isExtended = data.isExtended() && data.getClass().equals(FabricEntityTypeExtended.class);
|
||||
net.minecraft.entity.Entity entity;
|
||||
if(isExtended) {
|
||||
FabricEntityTypeExtended type = ((FabricEntityTypeExtended) data);
|
||||
NbtCompound nbt = (NbtCompound) ((Object) type.getData());
|
||||
entity = net.minecraft.entity.EntityType.loadEntityWithPassengers(nbt, this, SpawnReason.CHUNK_GENERATION, (entityx) -> {
|
||||
entityx.refreshPositionAndAngles(x, y, z, entityx.getYaw(), entityx.getPitch());
|
||||
return entityx;
|
||||
});
|
||||
spawnEntity(entity);
|
||||
} else {
|
||||
entity = ((net.minecraft.entity.EntityType<?>) data).create(this, SpawnReason.CHUNK_GENERATION);
|
||||
entity.setPos(x, y, z);
|
||||
spawnEntity(entity);
|
||||
}
|
||||
|
||||
return (Entity) entity;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user