mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2026-01-04 15:41:38 +00:00
添加方块实体
This commit is contained in:
@@ -169,7 +169,6 @@ public class BukkitBlockManager extends AbstractBlockManager {
|
||||
this.tempVanillaBlockStateModels.clear();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public Object getMinecraftBlockHolder(int stateId) {
|
||||
return stateId2BlockHolder.get(stateId);
|
||||
|
||||
@@ -388,7 +388,7 @@ public class BukkitInjector {
|
||||
// }
|
||||
// }
|
||||
|
||||
public static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEWorld ceWorld, CEChunk chunk, SectionPos pos) {
|
||||
public synchronized static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEWorld ceWorld, CEChunk chunk, SectionPos pos) {
|
||||
try {
|
||||
Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection);
|
||||
if (!clazz$InjectedPalettedContainer.isInstance(container)) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.momirealms.craftengine.core.block;
|
||||
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public class BlockEntityState {
|
||||
private final CompoundTag nbt;
|
||||
|
||||
public BlockEntityState(CompoundTag nbt) {
|
||||
this.nbt = nbt.deepClone();
|
||||
}
|
||||
|
||||
public CompoundTag nbt() {
|
||||
return nbt;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BannerSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
@@ -4,10 +4,8 @@ import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import software.amazon.awssdk.services.s3.endpoints.internal.Value;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ChestSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
@@ -8,7 +8,6 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ShulkerBoxSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
@@ -5,7 +5,6 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SignSpecialModel implements SpecialModel {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package net.momirealms.craftengine.core.world.chunk;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.momirealms.craftengine.core.block.BlockEntityState;
|
||||
import net.momirealms.craftengine.core.block.EmptyBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.world.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CEChunk {
|
||||
private boolean loaded;
|
||||
@@ -15,7 +16,7 @@ public class CEChunk {
|
||||
private final ChunkPos chunkPos;
|
||||
private final CESection[] sections;
|
||||
private final WorldHeight worldHeightAccessor;
|
||||
private final List<Vec3d> entities;
|
||||
private final Map<Integer, BlockEntityState> blockEntities;
|
||||
private boolean dirty;
|
||||
|
||||
public CEChunk(CEWorld world, ChunkPos chunkPos) {
|
||||
@@ -23,14 +24,14 @@ public class CEChunk {
|
||||
this.chunkPos = chunkPos;
|
||||
this.worldHeightAccessor = world.worldHeight();
|
||||
this.sections = new CESection[this.worldHeightAccessor.getSectionsCount()];
|
||||
this.entities = new ArrayList<>();
|
||||
this.blockEntities = new Int2ObjectOpenHashMap<>(16, 0.5f);
|
||||
this.fillEmptySection();
|
||||
}
|
||||
|
||||
public CEChunk(CEWorld world, ChunkPos chunkPos, CESection[] sections, List<Vec3d> entities) {
|
||||
public CEChunk(CEWorld world, ChunkPos chunkPos, CESection[] sections, Map<Integer, BlockEntityState> blockEntities) {
|
||||
this.world = world;
|
||||
this.chunkPos = chunkPos;
|
||||
this.entities = entities;
|
||||
this.blockEntities = blockEntities;
|
||||
this.worldHeightAccessor = world.worldHeight();
|
||||
int sectionCount = this.worldHeightAccessor.getSectionsCount();
|
||||
this.sections = new CESection[sectionCount];
|
||||
@@ -45,6 +46,10 @@ public class CEChunk {
|
||||
this.fillEmptySection();
|
||||
}
|
||||
|
||||
public Map<Integer, BlockEntityState> blockEntities() {
|
||||
return blockEntities;
|
||||
}
|
||||
|
||||
public boolean dirty() {
|
||||
return dirty;
|
||||
}
|
||||
@@ -54,7 +59,7 @@ public class CEChunk {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
if (!this.entities.isEmpty()) return false;
|
||||
if (!this.blockEntities.isEmpty()) return false;
|
||||
for (CESection section : this.sections) {
|
||||
if (section != null && !section.statesContainer().isEmpty()) {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.momirealms.craftengine.core.world.chunk.serialization;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.momirealms.craftengine.core.block.BlockEntityState;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.ListTag;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public final class DefaultBlockEntitySerializer {
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public static ListTag serialize(Map<Integer, BlockEntityState> tiles) {
|
||||
ListTag result = new ListTag();
|
||||
Map<CompoundTag, int[]> nbtToPosMap = new Object2ObjectOpenHashMap<>(Math.max(tiles.size(), 10), 0.75f);
|
||||
for (Map.Entry<Integer, BlockEntityState> entry : tiles.entrySet()) {
|
||||
int pos = entry.getKey();
|
||||
CompoundTag tag = entry.getValue().nbt();
|
||||
int[] previous = nbtToPosMap.computeIfAbsent(tag, k -> new int[] {pos});
|
||||
int[] newPoses = new int[previous.length + 1];
|
||||
System.arraycopy(previous, 0, newPoses, 0, previous.length);
|
||||
newPoses[previous.length] = pos;
|
||||
nbtToPosMap.put(tag, newPoses);
|
||||
}
|
||||
for (Map.Entry<CompoundTag, int[]> entry : nbtToPosMap.entrySet()) {
|
||||
CompoundTag blockEntityTag = new CompoundTag();
|
||||
blockEntityTag.put("data", entry.getKey());
|
||||
blockEntityTag.putIntArray("pos", entry.getValue());
|
||||
result.add(blockEntityTag);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public static Map<Integer, BlockEntityState> deserialize(ListTag tag) {
|
||||
Map<Integer, BlockEntityState> result = new Object2ObjectOpenHashMap<>(Math.max(tag.size(), 16), 0.5f);
|
||||
for (int i = 0; i < tag.size(); i++) {
|
||||
CompoundTag blockEntityTag = tag.getCompound(i);
|
||||
CompoundTag data = blockEntityTag.getCompound("data");
|
||||
int[] pos = blockEntityTag.getIntArray("pos");
|
||||
for (int j = 0; j < pos.length; j++) {
|
||||
result.put(j, new BlockEntityState(data));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,9 @@ import net.momirealms.sparrow.nbt.ListTag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class DefaultChunkSerializer {
|
||||
public final class DefaultChunkSerializer {
|
||||
|
||||
@Nullable
|
||||
public static CompoundTag serialize(@NotNull CEChunk chunk) {
|
||||
@@ -28,7 +28,7 @@ public class DefaultChunkSerializer {
|
||||
if (sections.isEmpty()) return null;
|
||||
CompoundTag chunkNbt = new CompoundTag();
|
||||
chunkNbt.put("sections", sections);
|
||||
chunkNbt.put("entities", new ListTag());
|
||||
chunkNbt.put("block_entities", DefaultBlockEntitySerializer.serialize(chunk.blockEntities()));
|
||||
return chunkNbt;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class DefaultChunkSerializer {
|
||||
}
|
||||
}
|
||||
}
|
||||
ListTag entities = chunkNbt.getList("entities");
|
||||
return new CEChunk(world, pos, sectionArray, List.of());
|
||||
ListTag blockEntities = Optional.ofNullable(chunkNbt.getList("block_entities")).orElse(new ListTag());
|
||||
return new CEChunk(world, pos, sectionArray, DefaultBlockEntitySerializer.deserialize(blockEntities));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
public class DefaultSectionSerializer {
|
||||
public final class DefaultSectionSerializer {
|
||||
|
||||
@Nullable
|
||||
public static CompoundTag serialize(@NotNull CESection section) {
|
||||
|
||||
Reference in New Issue
Block a user