mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-30 04:19:27 +00:00
方块实体,终
This commit is contained in:
@@ -7,6 +7,8 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.craftengine.bukkit.block.entity.renderer.BukkitBlockEntityElement;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.injector.BlockGenerator;
|
||||
@@ -23,7 +25,10 @@ import net.momirealms.craftengine.bukkit.util.RegistryUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.TagUtils;
|
||||
import net.momirealms.craftengine.core.block.*;
|
||||
import net.momirealms.craftengine.core.block.behavior.EmptyBlockBehavior;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement;
|
||||
import net.momirealms.craftengine.core.block.parser.BlockStateParser;
|
||||
import net.momirealms.craftengine.core.entity.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.ItemDisplayContext;
|
||||
import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
@@ -684,4 +689,20 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
||||
}
|
||||
return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.BLOCK, KeyUtils.toResourceLocation(id)) != MBlocks.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockEntityElement createBlockEntityElement(Map<String, Object> arguments) {
|
||||
Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), ""));
|
||||
return new BukkitBlockEntityElement(
|
||||
LazyReference.lazyReference(() -> BukkitItemManager.instance().createWrappedItem(itemId, null)),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("scale", 1f), "scale"),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position"),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.get("translation"), "translation"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("pitch", 0f), "pitch"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("yaw", 0f), "yaw"),
|
||||
ResourceConfigUtils.getAsQuaternionf(arguments.getOrDefault("rotation", 0f), "rotation"),
|
||||
ItemDisplayContext.valueOf(arguments.getOrDefault("display-context", "none").toString().toUpperCase(Locale.ROOT)),
|
||||
Billboard.valueOf(arguments.getOrDefault("billboard", "fixed").toString().toUpperCase(Locale.ROOT))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
|
||||
@NotNull Key id,
|
||||
@NotNull Holder.Reference<CustomBlock> holder,
|
||||
@NotNull Map<String, Property<?>> properties,
|
||||
@NotNull Map<String, Integer> appearances,
|
||||
@NotNull Map<String, BlockStateAppearance> appearances,
|
||||
@NotNull Map<String, BlockStateVariant> variantMapper,
|
||||
@NotNull BlockSettings settings,
|
||||
@NotNull Map<EventTrigger, List<Function<PlayerOptionalContext>>> events,
|
||||
@@ -200,7 +200,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
|
||||
public static class BuilderImpl implements Builder {
|
||||
protected final Key id;
|
||||
protected Map<String, Property<?>> properties;
|
||||
protected Map<String, Integer> appearances;
|
||||
protected Map<String, BlockStateAppearance> appearances;
|
||||
protected Map<String, BlockStateVariant> variantMapper;
|
||||
protected BlockSettings settings;
|
||||
protected List<Map<String, Object>> behavior;
|
||||
@@ -218,7 +218,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder appearances(Map<String, Integer> appearances) {
|
||||
public Builder appearances(Map<String, BlockStateAppearance> appearances) {
|
||||
this.appearances = appearances;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package net.momirealms.craftengine.bukkit.block.entity.renderer;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement;
|
||||
import net.momirealms.craftengine.core.entity.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.ItemDisplayContext;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.util.LazyReference;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitBlockEntityElement implements BlockEntityElement {
|
||||
private final LazyReference<List<Object>> lazyMetadataPacket;
|
||||
private final LazyReference<Item<?>> item;
|
||||
private final Vector3f scale;
|
||||
private final Vector3f position;
|
||||
private final Vector3f translation;
|
||||
private final float xRot;
|
||||
private final float yRot;
|
||||
private final Quaternionf rotation;
|
||||
private final ItemDisplayContext displayContext;
|
||||
private final Billboard billboard;
|
||||
|
||||
public BukkitBlockEntityElement(LazyReference<Item<?>> item,
|
||||
Vector3f scale,
|
||||
Vector3f position,
|
||||
Vector3f translation,
|
||||
float xRot,
|
||||
float yRot,
|
||||
Quaternionf rotation,
|
||||
ItemDisplayContext displayContext,
|
||||
Billboard billboard) {
|
||||
this.item = item;
|
||||
this.scale = scale;
|
||||
this.position = position;
|
||||
this.translation = translation;
|
||||
this.xRot = xRot;
|
||||
this.yRot = yRot;
|
||||
this.rotation = rotation;
|
||||
this.displayContext = displayContext;
|
||||
this.billboard = billboard;
|
||||
this.lazyMetadataPacket = LazyReference.lazyReference(() -> {
|
||||
List<Object> dataValues = new ArrayList<>();
|
||||
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.get().getLiteralObject(), dataValues);
|
||||
ItemDisplayEntityData.Scale.addEntityDataIfNotDefaultValue(this.scale, dataValues);
|
||||
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(this.rotation, dataValues);
|
||||
ItemDisplayEntityData.BillboardConstraints.addEntityDataIfNotDefaultValue(this.billboard.id(), dataValues);
|
||||
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(this.translation, dataValues);
|
||||
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(this.displayContext.id(), dataValues);
|
||||
return dataValues;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<?> item() {
|
||||
return this.item.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f scale() {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f translation() {
|
||||
return this.translation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f position() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float yRot() {
|
||||
return this.yRot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float xRot() {
|
||||
return this.xRot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Billboard billboard() {
|
||||
return billboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDisplayContext displayContext() {
|
||||
return displayContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Quaternionf rotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyReference<List<Object>> metadataValues() {
|
||||
return this.lazyMetadataPacket;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.momirealms.craftengine.bukkit.block.entity.renderer;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityRenderer;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityRendererConfig;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitBlockEntityRenderer extends BlockEntityRenderer {
|
||||
private final Object cachedSpawnPacket;
|
||||
private final Object cachedDespawnPacket;
|
||||
private final WeakReference<Object> chunkHolder;
|
||||
|
||||
public BukkitBlockEntityRenderer(WeakReference<Object> chunkHolder,
|
||||
BlockEntityRendererConfig config,
|
||||
BlockPos pos) {
|
||||
this.chunkHolder = chunkHolder;
|
||||
BlockEntityElement[] elements = config.elements();
|
||||
IntList ids = new IntArrayList(elements.length);
|
||||
List<Object> spawnPackets = new ArrayList<>(elements.length);
|
||||
for (BlockEntityElement element : elements) {
|
||||
int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
Vector3f position = element.position();
|
||||
spawnPackets.add(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z,
|
||||
element.xRot(), element.yRot(), MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
spawnPackets.add(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(
|
||||
entityId, element.metadataValues().get()
|
||||
));
|
||||
ids.add(entityId);
|
||||
}
|
||||
this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(spawnPackets);
|
||||
this.cachedDespawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void despawn() {
|
||||
List<Object> players = FastNMS.INSTANCE.method$ChunkHolder$getPlayers(this.chunkHolder.get());
|
||||
if (players.isEmpty()) return;
|
||||
for (Object player : players) {
|
||||
FastNMS.INSTANCE.method$ServerPlayerConnection$send(
|
||||
FastNMS.INSTANCE.field$Player$connection(player),
|
||||
this.cachedDespawnPacket
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn() {
|
||||
List<Object> players = FastNMS.INSTANCE.method$ChunkHolder$getPlayers(this.chunkHolder.get());
|
||||
if (players.isEmpty()) return;
|
||||
for (Object player : players) {
|
||||
FastNMS.INSTANCE.method$ServerPlayerConnection$send(
|
||||
FastNMS.INSTANCE.field$Player$connection(player),
|
||||
this.cachedSpawnPacket
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(Player player) {
|
||||
player.sendPacket(this.cachedSpawnPacket, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void despawn(Player player) {
|
||||
player.sendPacket(this.cachedDespawnPacket, false);
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,10 @@ public class DisplayEntityData<T> extends BaseEntityData<T> {
|
||||
public static final DisplayEntityData<Integer> TransformationInterpolationDuration = of(DisplayEntityData.class, EntityDataValue.Serializers$INT, 0, VersionHelper.isOrAbove1_20_2());
|
||||
public static final DisplayEntityData<Integer> PositionRotationInterpolationDuration = of(DisplayEntityData.class, EntityDataValue.Serializers$INT, 0, VersionHelper.isOrAbove1_20_2());
|
||||
|
||||
public static final DisplayEntityData<Object> Translation = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(0f), true);
|
||||
public static final DisplayEntityData<Object> Scale = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(1f), true);
|
||||
public static final DisplayEntityData<Object> RotationLeft = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true);
|
||||
public static final DisplayEntityData<Object> RotationRight = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true);
|
||||
public static final DisplayEntityData<Vector3f> Translation = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(0f), true);
|
||||
public static final DisplayEntityData<Vector3f> Scale = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(1f), true);
|
||||
public static final DisplayEntityData<Quaternionf> RotationLeft = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true);
|
||||
public static final DisplayEntityData<Quaternionf> RotationRight = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true);
|
||||
/**
|
||||
* Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER)
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.sound.SoundData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.bukkit.*;
|
||||
@@ -350,7 +351,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
plugin.logger().warn("Failed to get vector3f for player " + player.getName() + "'s seat");
|
||||
return;
|
||||
}
|
||||
Vector3f seatPos = MiscUtils.getAsVector3f(vector3f, "seat");
|
||||
Vector3f seatPos = ResourceConfigUtils.getAsVector3f(vector3f, "seat");
|
||||
furniture.removeOccupiedSeat(seatPos);
|
||||
|
||||
if (player.getVehicle() != null) return;
|
||||
|
||||
@@ -84,7 +84,7 @@ public class CustomHitBox extends AbstractHitBox {
|
||||
|
||||
@Override
|
||||
public HitBox create(Map<String, Object> arguments) {
|
||||
Vector3f position = MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
float scale = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("scale", 1), "scale");
|
||||
String type = (String) arguments.getOrDefault("entity-type", "slime");
|
||||
EntityType entityType = Registry.ENTITY_TYPE.get(new NamespacedKey("minecraft", type));
|
||||
|
||||
@@ -124,7 +124,7 @@ public class HappyGhastHitBox extends AbstractHitBox {
|
||||
boolean blocksBuilding = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blocks-building", true), "blocks-building");
|
||||
return new HappyGhastHitBox(
|
||||
HitBoxFactory.getSeats(arguments),
|
||||
MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"),
|
||||
scale, canUseOn, blocksBuilding, canBeHitByProjectile, hardCollision
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class InteractionHitBox extends AbstractHitBox {
|
||||
|
||||
@Override
|
||||
public HitBox create(Map<String, Object> arguments) {
|
||||
Vector3f position = MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
float width;
|
||||
float height;
|
||||
if (arguments.containsKey("scale")) {
|
||||
|
||||
@@ -280,7 +280,7 @@ public class ShulkerHitBox extends AbstractHitBox {
|
||||
|
||||
@Override
|
||||
public HitBox create(Map<String, Object> arguments) {
|
||||
Vector3f position = MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
float scale = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("scale", "1"), "scale");
|
||||
byte peek = (byte) ResourceConfigUtils.getAsInt(arguments.getOrDefault("peek", 0), "peek");
|
||||
Direction directionEnum = Optional.ofNullable(arguments.get("direction")).map(it -> Direction.valueOf(it.toString().toUpperCase(Locale.ENGLISH))).orElse(Direction.UP);
|
||||
|
||||
@@ -144,7 +144,7 @@ public class BukkitGuiManager implements GuiManager, Listener {
|
||||
simpleStorageBlockEntity.onPlayerClose(this.plugin.adapt(player));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void onInventoryClose(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.momirealms.craftengine.bukkit.world;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.entity.renderer.BukkitBlockEntityRenderer;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.LightUtils;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityRenderer;
|
||||
import net.momirealms.craftengine.core.block.entity.render.BlockEntityRendererConfig;
|
||||
@@ -7,10 +9,13 @@ import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.util.SectionPosUtils;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.CEWorld;
|
||||
import net.momirealms.craftengine.core.world.ChunkPos;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor;
|
||||
import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class BukkitCEWorld extends CEWorld {
|
||||
|
||||
public BukkitCEWorld(World world, StorageAdaptor adaptor) {
|
||||
@@ -41,6 +46,10 @@ public class BukkitCEWorld extends CEWorld {
|
||||
|
||||
@Override
|
||||
public BlockEntityRenderer createBlockEntityRenderer(BlockEntityRendererConfig config, BlockPos pos) {
|
||||
return null;
|
||||
Object serverLevel = this.world.serverWorld();
|
||||
Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel);
|
||||
long chunkKey = ChunkPos.asLong(pos.x() >> 4, pos.z() >> 4);
|
||||
Object chunkHolder = FastNMS.INSTANCE.method$ServerChunkCache$getVisibleChunkIfPresent(chunkSource, chunkKey);
|
||||
return new BukkitBlockEntityRenderer(new WeakReference<>(chunkHolder), config, pos);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user