9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

修复错误的id删除

This commit is contained in:
XiaoMoMi
2025-12-04 04:22:34 +08:00
parent a156942344
commit 14b0c71147
15 changed files with 128 additions and 47 deletions

View File

@@ -330,7 +330,7 @@ public final class CraftEngineFurniture {
public static BukkitFurniture getLoadedFurnitureByCollider(@NotNull Entity collider) { public static BukkitFurniture getLoadedFurnitureByCollider(@NotNull Entity collider) {
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(collider); Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(collider);
if (nmsEntity instanceof CollisionEntity collisionEntity) { if (nmsEntity instanceof CollisionEntity collisionEntity) {
return BukkitFurnitureManager.instance().loadedFurnitureByColliderEntityId(collisionEntity.getId()); return BukkitFurnitureManager.instance().loadedFurnitureByColliderEntityId(collisionEntity.getEntityId());
} }
return null; return null;
} }

View File

@@ -21,7 +21,7 @@ public class BukkitCollider implements Collider {
@Override @Override
public int entityId() { public int entityId() {
return this.collisionEntity.getId(); return this.collisionEntity.getEntityId();
} }
@Override @Override

View File

@@ -31,10 +31,12 @@ public class BukkitFurniture extends Furniture {
public void addCollidersToWorld() { public void addCollidersToWorld() {
Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.location.getWorld()); Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.location.getWorld());
for (Collider entity : super.colliders) { for (Collider entity : super.colliders) {
FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(world, entity.handle());
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity.handle()); Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity.handle());
bukkitEntity.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_COLLISION, PersistentDataType.BYTE, (byte) 1); bukkitEntity.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_COLLISION, PersistentDataType.BYTE, (byte) 1);
bukkitEntity.setPersistent(false); bukkitEntity.setPersistent(false);
if (!bukkitEntity.isValid()) {
FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(world, entity.handle());
}
} }
} }

View File

@@ -1,15 +1,19 @@
package net.momirealms.craftengine.bukkit.entity.furniture; package net.momirealms.craftengine.bukkit.entity.furniture;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.entity.furniture.hitbox.InteractionFurnitureHitboxConfig; import net.momirealms.craftengine.bukkit.entity.furniture.hitbox.InteractionFurnitureHitboxConfig;
import net.momirealms.craftengine.bukkit.nms.CollisionEntity; import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.EntityUtils; import net.momirealms.craftengine.bukkit.util.EntityUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.core.entity.furniture.*; import net.momirealms.craftengine.core.entity.furniture.*;
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig; import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.sound.SoundData; import net.momirealms.craftengine.core.sound.SoundData;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
@@ -29,6 +33,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class BukkitFurnitureManager extends AbstractFurnitureManager { public class BukkitFurnitureManager extends AbstractFurnitureManager {
public static final NamespacedKey FURNITURE_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_KEY); public static final NamespacedKey FURNITURE_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_KEY);
@@ -73,7 +78,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
} catch (IOException e) { } catch (IOException e) {
this.plugin.logger().warn("Failed to set furniture PDC for " + furniture.id().toString(), e); this.plugin.logger().warn("Failed to set furniture PDC for " + furniture.id().toString(), e);
} }
handleMetaEntityAfterChunkLoad(display); handleMetaEntityDuringChunkLoad(display);
}); });
if (playSound) { if (playSound) {
SoundData sound = furniture.settings().sounds().placeSound(); SoundData sound = furniture.settings().sounds().placeSound();
@@ -228,6 +233,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
createFurnitureInstance(entity, customFurniture); createFurnitureInstance(entity, customFurniture);
} }
@SuppressWarnings("deprecation")
protected void handleMetaEntityAfterChunkLoad(ItemDisplay entity) { protected void handleMetaEntityAfterChunkLoad(ItemDisplay entity) {
// 实体可能不是持久的 // 实体可能不是持久的
if (!entity.isPersistent()) { if (!entity.isPersistent()) {
@@ -239,7 +245,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
if (id == null) return; if (id == null) return;
// 这个区块还处于加载实体中,这个时候不处理 // 这个区块还处于加载实体中,这个时候不处理
if (!isEntitiesLoaded(entity.getLocation())) { Location location = entity.getLocation();
if (!isEntitiesLoaded(location)) {
return; return;
} }
@@ -254,13 +261,16 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
if (previous != null) return; if (previous != null) return;
createFurnitureInstance(entity, customFurniture); createFurnitureInstance(entity, customFurniture);
// 补发一次包
for (Player player : entity.getTrackedPlayers()) {
BukkitAdaptors.adapt(player).sendPacket(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entity.getEntityId(), entity.getUniqueId(), location.getX(), location.getY(), location.getZ(), location.getPitch(), location.getYaw(),
MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0
), false);
}
} }
protected void handleCollisionEntityAfterChunkLoad(Entity entity) { protected void handleCollisionEntityAfterChunkLoad(Entity entity) {
// 实体可能不是持久的
if (!entity.isPersistent()) {
return;
}
// 如果是碰撞实体,那么就忽略 // 如果是碰撞实体,那么就忽略
if (FastNMS.INSTANCE.method$CraftEntity$getHandle(entity) instanceof CollisionEntity) { if (FastNMS.INSTANCE.method$CraftEntity$getHandle(entity) instanceof CollisionEntity) {
return; return;
@@ -271,11 +281,13 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
return; return;
} }
// 实体未加载 // 实体未加载
if (!isEntitiesLoaded(entity.getLocation())) { Location location = entity.getLocation();
if (!isEntitiesLoaded(location)) {
return; return;
} }
// 移除被WorldEdit错误复制的碰撞实体 // 移除被WorldEdit错误复制的碰撞实体
entity.remove(); runSafeEntityOperation(location, entity::remove);
} }
public void handleCollisionEntityDuringChunkLoad(Entity collisionEntity) { public void handleCollisionEntityDuringChunkLoad(Entity collisionEntity) {
@@ -306,7 +318,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
} }
// 创建家具实例,并初始化碰撞实体 // 创建家具实例,并初始化碰撞实体
private void createFurnitureInstance(ItemDisplay display, FurnitureConfig furniture) { private BukkitFurniture createFurnitureInstance(ItemDisplay display, FurnitureConfig furniture) {
BukkitFurniture bukkitFurniture = new BukkitFurniture(display, furniture, getFurnitureDataAccessor(display)); BukkitFurniture bukkitFurniture = new BukkitFurniture(display, furniture, getFurnitureDataAccessor(display));
this.byMetaEntityId.put(display.getEntityId(), bukkitFurniture); this.byMetaEntityId.put(display.getEntityId(), bukkitFurniture);
for (int entityId : bukkitFurniture.virtualEntityIds()) { for (int entityId : bukkitFurniture.virtualEntityIds()) {
@@ -315,7 +327,18 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
for (Collider collisionEntity : bukkitFurniture.colliders()) { for (Collider collisionEntity : bukkitFurniture.colliders()) {
this.byColliderEntityId.put(collisionEntity.entityId(), bukkitFurniture); this.byColliderEntityId.put(collisionEntity.entityId(), bukkitFurniture);
} }
bukkitFurniture.addCollidersToWorld(); Location location = display.getLocation();
runSafeEntityOperation(location, bukkitFurniture::addCollidersToWorld);
return bukkitFurniture;
}
private void runSafeEntityOperation(Location location, Runnable action) {
boolean preventChange = FastNMS.INSTANCE.method$ServerLevel$isPreventingStatusUpdates(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()), location.getBlockX() >> 4, location.getBlockZ() >> 4);
if (preventChange) {
this.plugin.scheduler().sync().runLater(action, 1, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
} else {
action.run();
}
} }
@Override @Override

View File

@@ -27,6 +27,7 @@ public class CustomFurnitureHitbox extends AbstractFurnitureHitBox {
private final Object spawnPacket; private final Object spawnPacket;
private final Object despawnPacket; private final Object despawnPacket;
private final FurnitureHitboxPart part; private final FurnitureHitboxPart part;
private final int entityId;
public CustomFurnitureHitbox(Furniture furniture, CustomFurnitureHitboxConfig config) { public CustomFurnitureHitbox(Furniture furniture, CustomFurnitureHitboxConfig config) {
super(furniture, config); super(furniture, config);
@@ -54,6 +55,7 @@ public class CustomFurnitureHitbox extends AbstractFurnitureHitBox {
this.spawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets); this.spawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets);
this.part = new FurnitureHitboxPart(entityId, aabb, pos, false); this.part = new FurnitureHitboxPart(entityId, aabb, pos, false);
this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList() {{ add(entityId); }}); this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList() {{ add(entityId); }});
this.entityId = entityId;
} }
@Override @Override
@@ -76,6 +78,11 @@ public class CustomFurnitureHitbox extends AbstractFurnitureHitBox {
player.sendPacket(this.despawnPacket, false); player.sendPacket(this.despawnPacket, false);
} }
@Override
public void collectVirtualEntityId(Consumer<Integer> collector) {
collector.accept(this.entityId);
}
@Override @Override
public CustomFurnitureHitboxConfig config() { public CustomFurnitureHitboxConfig config() {
return this.config; return this.config;

View File

@@ -83,6 +83,11 @@ public class HappyGhastFurnitureHitbox extends AbstractFurnitureHitBox {
player.sendPacket(this.despawnPacket, false); player.sendPacket(this.despawnPacket, false);
} }
@Override
public void collectVirtualEntityId(Consumer<Integer> collector) {
collector.accept(this.entityId);
}
@Override @Override
public HappyGhastFurnitureHitboxConfig config() { public HappyGhastFurnitureHitboxConfig config() {
return this.config; return this.config;

View File

@@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.world.collision.AABB;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer;
public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox { public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
private final InteractionFurnitureHitboxConfig config; private final InteractionFurnitureHitboxConfig config;
@@ -21,6 +22,7 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
private final Object spawnPacket; private final Object spawnPacket;
private final Object despawnPacket; private final Object despawnPacket;
private final FurnitureHitboxPart part; private final FurnitureHitboxPart part;
private final int entityId;
public InteractionFurnitureHitbox(Furniture furniture, InteractionFurnitureHitboxConfig config) { public InteractionFurnitureHitbox(Furniture furniture, InteractionFurnitureHitboxConfig config) {
super(furniture, config); super(furniture, config);
@@ -39,6 +41,7 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
)); ));
this.part = new FurnitureHitboxPart(interactionId, aabb, pos, config.responsive()); this.part = new FurnitureHitboxPart(interactionId, aabb, pos, config.responsive());
this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList() {{ add(interactionId); }}); this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList() {{ add(interactionId); }});
this.entityId = interactionId;
} }
@Override @Override
@@ -56,6 +59,11 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
return this.config; return this.config;
} }
@Override
public void collectVirtualEntityId(Consumer<Integer> collector) {
collector.accept(this.entityId);
}
@Override @Override
public void show(Player player) { public void show(Player player) {
player.sendPacket(this.spawnPacket, false); player.sendPacket(this.spawnPacket, false);

View File

@@ -17,10 +17,7 @@ import net.momirealms.craftengine.core.world.WorldPosition;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3f; import org.joml.Vector3f;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -30,11 +27,12 @@ public class ShulkerFurnitureHitbox extends AbstractFurnitureHitBox {
private final List<Collider> colliders; private final List<Collider> colliders;
private final Object spawnPacket; private final Object spawnPacket;
private final Object despawnPacket; private final Object despawnPacket;
private final int[] entityIds;
public ShulkerFurnitureHitbox(Furniture furniture, ShulkerFurnitureHitboxConfig config) { public ShulkerFurnitureHitbox(Furniture furniture, ShulkerFurnitureHitboxConfig config) {
super(furniture, config); super(furniture, config);
this.config = config; this.config = config;
int[] entityIds = acquireEntityIds(CoreReflections.instance$Entity$ENTITY_COUNTER::incrementAndGet); this.entityIds = acquireEntityIds(CoreReflections.instance$Entity$ENTITY_COUNTER::incrementAndGet);
WorldPosition position = furniture.position(); WorldPosition position = furniture.position();
Quaternionf conjugated = QuaternionUtils.toQuaternionf(0f, (float) Math.toRadians(180 - position.yRot()), 0f).conjugate(); Quaternionf conjugated = QuaternionUtils.toQuaternionf(0f, (float) Math.toRadians(180 - position.yRot()), 0f).conjugate();
Vector3f offset = conjugated.transform(new Vector3f(config.position())); Vector3f offset = conjugated.transform(new Vector3f(config.position()));
@@ -99,6 +97,13 @@ public class ShulkerFurnitureHitbox extends AbstractFurnitureHitBox {
return this.parts; return this.parts;
} }
@Override
public void collectVirtualEntityId(Consumer<Integer> collector) {
for (int entityId : entityIds) {
collector.accept(entityId);
}
}
@Override @Override
public void show(Player player) { public void show(Player player) {
player.sendPacket(this.spawnPacket, false); player.sendPacket(this.spawnPacket, false);

View File

@@ -80,10 +80,8 @@ public class ShulkerFurnitureHitboxConfig extends AbstractFurnitureHitBoxConfig<
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
)); ));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues))); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)));
if (canUseItemOn) { Vec3d vec3d = new Vec3d(x + offset.x, y + offset.y, z - offset.z);
Vec3d vec3d = new Vec3d(x + offset.x, y + offset.y, z - offset.z); aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.makeBoundingBox(vec3d, scale, shulkerHeight), vec3d, interactive));
aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.makeBoundingBox(vec3d, scale, shulkerHeight), vec3d, interactive));
}
} }
}; };
this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.UP, offset, x, y, z); this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.UP, offset, x, y, z);
@@ -100,10 +98,8 @@ public class ShulkerFurnitureHitboxConfig extends AbstractFurnitureHitBoxConfig<
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
)); ));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues))); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)));
if (canUseItemOn) { Vec3d vec3d = new Vec3d(x + offset.x, y + offset.y - shulkerHeight + scale, z - offset.z);
Vec3d vec3d = new Vec3d(x + offset.x, y + offset.y - shulkerHeight + scale, z - offset.z); aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.makeBoundingBox(vec3d, scale, shulkerHeight), vec3d, interactive));
aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.makeBoundingBox(vec3d, scale, shulkerHeight), vec3d, interactive));
}
} }
}; };
this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.DOWN, offset, x, y, z); this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.DOWN, offset, x, y, z);
@@ -130,12 +126,10 @@ public class ShulkerFurnitureHitboxConfig extends AbstractFurnitureHitBoxConfig<
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0 MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
)); ));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[3], List.copyOf(cachedInteractionValues))); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[3], List.copyOf(cachedInteractionValues)));
if (canUseItemOn) { Vec3d vec3d1 = new Vec3d(x + offset.x, y + offset.y, z - offset.z);
Vec3d vec3d1 = new Vec3d(x + offset.x, y + offset.y, z - offset.z); Vec3d vec3d2 = new Vec3d(x + offset.x + shulkerDirection.stepX() * distance, y + offset.y, z - offset.z + shulkerDirection.stepZ() * distance);
Vec3d vec3d2 = new Vec3d(x + offset.x + shulkerDirection.stepX() * distance, y + offset.y, z - offset.z + shulkerDirection.stepZ() * distance); aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.makeBoundingBox(vec3d1, scale, scale), vec3d1, interactive));
aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.makeBoundingBox(vec3d1, scale, scale), vec3d1, interactive)); aabb.accept(new FurnitureHitboxPart(entityIds[3], AABB.makeBoundingBox(vec3d2, scale, scale), vec3d2, interactive));
aabb.accept(new FurnitureHitboxPart(entityIds[3], AABB.makeBoundingBox(vec3d2, scale, scale), vec3d2, interactive));
}
} }
}; };
this.aabbCreator = (x, y, z, yaw, offset) -> { this.aabbCreator = (x, y, z, yaw, offset) -> {

View File

@@ -3954,14 +3954,16 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user; BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user;
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(id); BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(id);
if (furniture != null) { if (furniture != null) {
serverPlayer.entityPacketHandlers().put(id, new FurniturePacketHandler(id, furniture.virtualEntityIds())); EntityPacketHandler previous = serverPlayer.entityPacketHandlers().put(id, new FurniturePacketHandler(id, furniture.virtualEntityIds()));
if (Config.enableEntityCulling()) { if (Config.enableEntityCulling()) {
serverPlayer.addTrackedFurniture(id, furniture); serverPlayer.addTrackedFurniture(id, furniture);
} else { } else {
furniture.show(serverPlayer); // 修复addEntityToWorld包比事件先发的问题 (WE)
if (previous == null || previous instanceof ItemDisplayPacketHandler) {
furniture.show(serverPlayer);
}
} }
// fixme 外部模型 if (Config.hideBaseEntity() && !furniture.hasExternalModel()) {
if (Config.hideBaseEntity() && true) {
event.setCancelled(true); event.setCancelled(true);
} }
} else { } else {

View File

@@ -558,7 +558,7 @@ chunk-system:
client-optimization: client-optimization:
# Requires a restart to fully apply. # Requires a restart to fully apply.
entity-culling: entity-culling:
enable: true enable: false
# Using server-side ray tracing algorithms to hide block entities/furniture and reduce client-side rendering pressure. # Using server-side ray tracing algorithms to hide block entities/furniture and reduce client-side rendering pressure.
ray-tracing: true ray-tracing: true
# Cull entities based on distance # Cull entities based on distance

View File

@@ -27,14 +27,25 @@ items:
billboard: FIXED billboard: FIXED
translation: 0,0.5,0 translation: 0,0.5,0
hitboxes: hitboxes:
- position: 0,0,0 $$>=1.20.5:
type: custom - position: 0,0,0
entity-type: slime type: custom
invisible: true entity-type: slime
can-use-item-on: true invisible: true
blocks-building: true can-use-item-on: true
seats: blocks-building: true
- 0,0,-0.1 0 seats:
- 0,0,-0.1 0
$$fallback:
- position: 0,0,0
type: interaction
blocks-building: true
invisible: true
width: 0.7
height: 1.2
interactive: true
seats:
- 0,0,-0.1 0
loot: loot:
template: default:loot_table/furniture template: default:loot_table/furniture
arguments: arguments:

View File

@@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.momirealms.craftengine.core.entity.AbstractEntity;
import net.momirealms.craftengine.core.entity.Entity; import net.momirealms.craftengine.core.entity.Entity;
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElement; import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElement;
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElementConfig; import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElementConfig;
@@ -13,6 +14,7 @@ import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxCo
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart; import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart;
import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.entity.seat.Seat; import net.momirealms.craftengine.core.entity.seat.Seat;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.entityculling.CullingData; import net.momirealms.craftengine.core.plugin.entityculling.CullingData;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.QuaternionUtils; import net.momirealms.craftengine.core.util.QuaternionUtils;
@@ -25,6 +27,7 @@ import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.joml.Vector3f; import org.joml.Vector3f;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public abstract class Furniture implements Cullable { public abstract class Furniture implements Cullable {
@@ -41,6 +44,8 @@ public abstract class Furniture implements Cullable {
protected int[] virtualEntityIds; protected int[] virtualEntityIds;
protected int[] colliderEntityIds; protected int[] colliderEntityIds;
private boolean hasExternalModel;
protected Furniture(Entity metaDataEntity, FurnitureDataAccessor data, FurnitureConfig config) { protected Furniture(Entity metaDataEntity, FurnitureDataAccessor data, FurnitureConfig config) {
this.config = config; this.config = config;
this.dataAccessor = data; this.dataAccessor = data;
@@ -77,8 +82,8 @@ public abstract class Furniture implements Cullable {
this.hitboxes[i] = hitbox; this.hitboxes[i] = hitbox;
for (FurnitureHitboxPart part : hitbox.parts()) { for (FurnitureHitboxPart part : hitbox.parts()) {
this.hitboxMap.put(part.entityId(), hitbox); this.hitboxMap.put(part.entityId(), hitbox);
virtualEntityIds.add(part.entityId());
} }
hitbox.collectVirtualEntityId(virtualEntityIds::addLast);
colliders.addAll(hitbox.colliders()); colliders.addAll(hitbox.colliders());
} }
// 虚拟碰撞箱的实体id // 虚拟碰撞箱的实体id
@@ -86,6 +91,18 @@ public abstract class Furniture implements Cullable {
this.colliders = colliders.toArray(new Collider[0]); this.colliders = colliders.toArray(new Collider[0]);
this.colliderEntityIds = colliders.stream().mapToInt(Collider::entityId).toArray(); this.colliderEntityIds = colliders.stream().mapToInt(Collider::entityId).toArray();
this.cullingData = createCullingData(variant.cullingData()); this.cullingData = createCullingData(variant.cullingData());
// 外部模型
Optional<ExternalModel> externalModel = variant.externalModel();
if (externalModel.isPresent()) {
this.hasExternalModel = true;
try {
externalModel.get().bindModel((AbstractEntity) this.metaDataEntity);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to load external model for furniture " + id(), e);
}
} else {
this.hasExternalModel = false;
}
} }
private CullingData createCullingData(CullingData parent) { private CullingData createCullingData(CullingData parent) {
@@ -181,6 +198,10 @@ public abstract class Furniture implements Cullable {
return this.metaDataEntity.entityID(); return this.metaDataEntity.entityID();
} }
public boolean hasExternalModel() {
return hasExternalModel;
}
public Vec3d getRelativePosition(Vector3f position) { public Vec3d getRelativePosition(Vector3f position) {
return getRelativePosition(this.position(), position); return getRelativePosition(this.position(), position);
} }

View File

@@ -9,6 +9,7 @@ import net.momirealms.craftengine.core.world.Vec3d;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer;
public interface FurnitureHitBox extends SeatOwner { public interface FurnitureHitBox extends SeatOwner {
@@ -24,6 +25,8 @@ public interface FurnitureHitBox extends SeatOwner {
FurnitureHitBoxConfig<?> config(); FurnitureHitBoxConfig<?> config();
void collectVirtualEntityId(Consumer<Integer> collector);
default Optional<EntityHitResult> clip(Vec3d min, Vec3d max) { default Optional<EntityHitResult> clip(Vec3d min, Vec3d max) {
for (FurnitureHitboxPart value : parts()) { for (FurnitureHitboxPart value : parts()) {
Optional<EntityHitResult> clip = value.aabb().clip(min, max); Optional<EntityHitResult> clip = value.aabb().clip(min, max);

View File

@@ -48,7 +48,7 @@ byte_buddy_version=1.18.1
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.5 snake_yaml_version=2.5
anti_grief_version=1.0.5 anti_grief_version=1.0.5
nms_helper_version=1.0.138 nms_helper_version=1.0.140
evalex_version=3.5.0 evalex_version=3.5.0
reactive_streams_version=1.0.4 reactive_streams_version=1.0.4
amazon_awssdk_version=2.38.7 amazon_awssdk_version=2.38.7