mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
家具重构part4
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
package net.momirealms.craftengine.bukkit.api.event;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureVariant;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@@ -153,7 +153,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
|
||||
// 当元数据实体被卸载了
|
||||
protected void handleMetaEntityUnload(Entity entity) {
|
||||
protected void handleMetaEntityUnload(ItemDisplay entity) {
|
||||
// 不是持久化的
|
||||
if (!entity.isPersistent()) {
|
||||
return;
|
||||
|
||||
@@ -75,8 +75,8 @@ public class FurnitureEventListener implements Listener {
|
||||
public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
Entity[] entities = event.getChunk().getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay) {
|
||||
this.manager.handleMetaEntityUnload(entity);
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleMetaEntityUnload(itemDisplay);
|
||||
} else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) {
|
||||
this.manager.handleCollisionEntityUnload(entity);
|
||||
}
|
||||
@@ -87,8 +87,8 @@ public class FurnitureEventListener implements Listener {
|
||||
public void onWorldUnload(WorldUnloadEvent event) {
|
||||
List<Entity> entities = event.getWorld().getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay) {
|
||||
this.manager.handleMetaEntityUnload(entity);
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleMetaEntityUnload(itemDisplay);
|
||||
} else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) {
|
||||
this.manager.handleCollisionEntityUnload(entity);
|
||||
}
|
||||
@@ -98,8 +98,8 @@ public class FurnitureEventListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onEntityUnload(EntityRemoveFromWorldEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity instanceof ItemDisplay) {
|
||||
this.manager.handleMetaEntityUnload(entity);
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleMetaEntityUnload(itemDisplay);
|
||||
} else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) {
|
||||
this.manager.handleCollisionEntityUnload(entity);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ package net.momirealms.craftengine.bukkit.entity.furniture.element;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureColorSource;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.core.entity.display.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.display.ItemDisplayContext;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureColorSource;
|
||||
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElementConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElementConfigFactory;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitCollider;
|
||||
import net.momirealms.craftengine.bukkit.entity.seat.BukkitSeat;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
@@ -8,7 +7,6 @@ import net.momirealms.craftengine.core.entity.furniture.Collider;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBox;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.entity.seat.Seat;
|
||||
import net.momirealms.craftengine.core.entity.seat.SeatConfig;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
@@ -51,13 +49,4 @@ public abstract class AbstractFurnitureHitBox implements FurnitureHitBox {
|
||||
Object nmsAABB = FastNMS.INSTANCE.constructor$AABB(ceAABB.minX, ceAABB.minY, ceAABB.minZ, ceAABB.maxX, ceAABB.maxY, ceAABB.maxZ);
|
||||
return new BukkitCollider(world.serverWorld(), nmsAABB, position.x, position.y, position.z, canBeHitByProjectile, canCollide, blocksBuilding);
|
||||
}
|
||||
|
||||
protected Object createDespawnPacket(int[] entityIds) {
|
||||
return FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList(entityIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Player player) {
|
||||
player.sendPacket(createDespawnPacket(this.virtualEntityIds()), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ public class BukkitFurnitureHitboxTypes extends FurnitureHitBoxTypes {
|
||||
|
||||
static {
|
||||
register(INTERACTION, InteractionFurnitureHitboxConfig.FACTORY);
|
||||
// register(SHULKER, ShulkerFurnitureHitboxConfig.FACTORY);
|
||||
register(SHULKER, ShulkerFurnitureHitboxConfig.FACTORY);
|
||||
// register(HAPPY_GHAST, HappyGhastFurnitureHitboxConfig.FACTORY);
|
||||
// register(CUSTOM, CustomFurnitureHitboxConfig.FACTORY);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.momirealms.craftengine.bukkit.entity.data.BaseEntityData;
|
||||
import net.momirealms.craftengine.bukkit.entity.data.InteractionEntityData;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
@@ -7,6 +8,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Collider;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
@@ -15,24 +17,22 @@ import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
private final InteractionFurnitureHitboxConfig config;
|
||||
private final Vec3d position;
|
||||
private final AABB aabb;
|
||||
private final Collider collider;
|
||||
private final int interactionId;
|
||||
private final Object spawnPacket;
|
||||
private final Object despawnPacket;
|
||||
private final FurnitureHitboxPart part;
|
||||
|
||||
public InteractionFurnitureHitbox(Furniture furniture, InteractionFurnitureHitboxConfig config) {
|
||||
super(furniture, config);
|
||||
this.config = config;
|
||||
WorldPosition position = furniture.position();
|
||||
this.position = Furniture.getRelativePosition(position, config.position());
|
||||
this.aabb = AABB.fromInteraction(this.position, config.size.x, config.size.y);
|
||||
this.collider = createCollider(furniture.world(), this.position, this.aabb, false, config.blocksBuilding(), config.canBeHitByProjectile());
|
||||
this.interactionId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
Vec3d pos = Furniture.getRelativePosition(position, config.position());
|
||||
AABB aabb = AABB.fromInteraction(pos, config.size.x, config.size.y);
|
||||
this.collider = createCollider(furniture.world(), pos, aabb, false, config.blocksBuilding(), config.canBeHitByProjectile());
|
||||
int interactionId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
List<Object> values = new ArrayList<>(4);
|
||||
InteractionEntityData.Height.addEntityDataIfNotDefaultValue(config.size.y, values);
|
||||
InteractionEntityData.Width.addEntityDataIfNotDefaultValue(config.size.x, values);
|
||||
@@ -42,11 +42,28 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
}
|
||||
this.spawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(List.of(
|
||||
FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
this.interactionId, UUID.randomUUID(), position.x, position.y, position.z, 0, position.yRot,
|
||||
interactionId, UUID.randomUUID(), position.x, position.y, position.z, 0, position.yRot,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
),
|
||||
FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.interactionId, values)
|
||||
FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(interactionId, values)
|
||||
));
|
||||
this.part = new FurnitureHitboxPart(interactionId, aabb, pos);
|
||||
this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList() {{ add(interactionId); }});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Collider> colliders() {
|
||||
return List.of(this.collider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FurnitureHitboxPart> parts() {
|
||||
return List.of(this.part);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionFurnitureHitboxConfig config() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,31 +72,7 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AABB[] aabb() {
|
||||
return new AABB[] { this.aabb };
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d position() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Collider> colliders() {
|
||||
return List.of(this.collider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] virtualEntityIds() {
|
||||
return new int[] { this.interactionId };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectVirtualEntityIds(Consumer<Integer> collector) {
|
||||
collector.accept(this.interactionId);
|
||||
}
|
||||
|
||||
public InteractionFurnitureHitboxConfig config() {
|
||||
return this.config;
|
||||
public void hide(Player player) {
|
||||
player.sendPacket(this.despawnPacket, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MAttributeHolders;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Collider;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.QuaternionUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ShulkerFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
private final ShulkerFurnitureHitboxConfig config;
|
||||
private final List<FurnitureHitboxPart> parts;
|
||||
private final List<Collider> colliders;
|
||||
private final Object spawnPacket;
|
||||
private final Object despawnPacket;
|
||||
|
||||
public ShulkerFurnitureHitbox(Furniture furniture, ShulkerFurnitureHitboxConfig config) {
|
||||
super(furniture, config);
|
||||
this.config = config;
|
||||
int[] entityIds = acquireEntityIds(CoreReflections.instance$Entity$ENTITY_COUNTER::incrementAndGet);
|
||||
WorldPosition position = furniture.position();
|
||||
Quaternionf conjugated = QuaternionUtils.toQuaternionf(0f, (float) Math.toRadians(180 - position.yRot()), 0f).conjugate();
|
||||
Vector3f offset = conjugated.transform(new Vector3f(config.position()));
|
||||
double x = position.x();
|
||||
double y = position.y();
|
||||
double z = position.z();
|
||||
float yaw = position.yRot();
|
||||
double originalY = y + offset.y;
|
||||
double integerPart = Math.floor(originalY);
|
||||
double fractionalPart = originalY - integerPart;
|
||||
double processedY = (fractionalPart >= 0.5) ? integerPart + 1 : originalY;
|
||||
List<Object> packets = new ArrayList<>();
|
||||
List<Collider> colliders = new ArrayList<>();
|
||||
List<FurnitureHitboxPart> parts = new ArrayList<>();
|
||||
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityIds[0], UUID.randomUUID(), x + offset.x, originalY, z - offset.z, 0, yaw,
|
||||
MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityIds[1], UUID.randomUUID(), x + offset.x, processedY, z - offset.z, 0, yaw,
|
||||
MEntityTypes.SHULKER, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[1], List.copyOf(config.cachedShulkerValues)));
|
||||
packets.add(FastNMS.INSTANCE.constructor$ClientboundSetPassengersPacket(entityIds[0], entityIds[1]));
|
||||
|
||||
// fix some special occasions
|
||||
if (originalY != processedY) {
|
||||
double deltaY = originalY - processedY;
|
||||
short ya = (short) (deltaY * 8192);
|
||||
try {
|
||||
packets.add(NetworkReflections.constructor$ClientboundMoveEntityPacket$Pos.newInstance(
|
||||
entityIds[1], (short) 0, ya, (short) 0, true
|
||||
));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to construct ClientboundMoveEntityPacket$Pos", e);
|
||||
}
|
||||
}
|
||||
if (VersionHelper.isOrAbove1_20_5() && config.scale != 1) {
|
||||
try {
|
||||
Object attributeInstance = CoreReflections.constructor$AttributeInstance.newInstance(MAttributeHolders.SCALE, (Consumer<?>) (o) -> {});
|
||||
CoreReflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, config.scale);
|
||||
packets.add(NetworkReflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[1], Collections.singletonList(attributeInstance)));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to apply scale attribute", e);
|
||||
}
|
||||
}
|
||||
config.spawner.accept(entityIds, position.world(), x, y, z, yaw, offset, packets::add, colliders::add, parts::add);
|
||||
this.parts = parts;
|
||||
this.colliders = colliders;
|
||||
this.spawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets);
|
||||
this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList(entityIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Collider> colliders() {
|
||||
return this.colliders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FurnitureHitboxPart> parts() {
|
||||
return this.parts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Player player) {
|
||||
player.sendPacket(this.spawnPacket, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Player player) {
|
||||
player.sendPacket(this.despawnPacket, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShulkerFurnitureHitboxConfig config() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
public int[] acquireEntityIds(Supplier<Integer> entityIdSupplier) {
|
||||
if (config.interactionEntity) {
|
||||
if (config.direction.stepY() != 0) {
|
||||
// 展示实体 // 潜影贝 // 交互实体
|
||||
return new int[] {entityIdSupplier.get(), entityIdSupplier.get(), entityIdSupplier.get()};
|
||||
} else {
|
||||
// 展示实体 // 潜影贝 // 交互实体1 // 交互实体2
|
||||
return new int[] {entityIdSupplier.get(), entityIdSupplier.get(), entityIdSupplier.get(), entityIdSupplier.get()};
|
||||
}
|
||||
} else {
|
||||
// 展示实体 // 潜影贝
|
||||
return new int[] {entityIdSupplier.get(), entityIdSupplier.get()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.data.InteractionEntityData;
|
||||
import net.momirealms.craftengine.bukkit.entity.data.ShulkerData;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitCollider;
|
||||
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.bukkit.util.DirectionUtils;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Collider;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.AbstractFurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfigFactory;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart;
|
||||
import net.momirealms.craftengine.core.entity.seat.SeatConfig;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.QuaternionUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ShulkerFurnitureHitboxConfig extends AbstractFurnitureHitBoxConfig<ShulkerFurnitureHitbox> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public final float scale;
|
||||
public final byte peek;
|
||||
public final boolean interactive;
|
||||
public final boolean interactionEntity;
|
||||
public final Direction direction;
|
||||
public final DirectionalShulkerSpawner spawner;
|
||||
public final List<Object> cachedShulkerValues = new ArrayList<>();
|
||||
public final AABBCreator aabbCreator;
|
||||
|
||||
public ShulkerFurnitureHitboxConfig(SeatConfig[] seats,
|
||||
Vector3f position,
|
||||
boolean canUseItemOn,
|
||||
boolean blocksBuilding,
|
||||
boolean canBeHitByProjectile,
|
||||
float scale,
|
||||
byte peek,
|
||||
boolean interactive,
|
||||
boolean interactionEntity,
|
||||
Direction direction) {
|
||||
super(seats, position, canUseItemOn, blocksBuilding, canBeHitByProjectile);
|
||||
this.scale = scale;
|
||||
this.peek = peek;
|
||||
this.interactive = interactive;
|
||||
this.interactionEntity = interactionEntity;
|
||||
this.direction = direction;
|
||||
|
||||
ShulkerData.Peek.addEntityDataIfNotDefaultValue(peek, this.cachedShulkerValues);
|
||||
ShulkerData.Color.addEntityDataIfNotDefaultValue((byte) 0, this.cachedShulkerValues);
|
||||
ShulkerData.NoGravity.addEntityDataIfNotDefaultValue(true, this.cachedShulkerValues);
|
||||
ShulkerData.Silent.addEntityDataIfNotDefaultValue(true, this.cachedShulkerValues);
|
||||
ShulkerData.MobFlags.addEntityDataIfNotDefaultValue((byte) 0x01, this.cachedShulkerValues); // NO AI
|
||||
ShulkerData.SharedFlags.addEntityDataIfNotDefaultValue((byte) 0x20, this.cachedShulkerValues); // Invisible
|
||||
|
||||
List<Object> cachedInteractionValues = new ArrayList<>();
|
||||
float shulkerHeight = (getPhysicalPeek(peek * 0.01F) + 1) * scale;
|
||||
if (direction == Direction.UP) {
|
||||
InteractionEntityData.Height.addEntityDataIfNotDefaultValue(shulkerHeight + 0.01f, cachedInteractionValues);
|
||||
InteractionEntityData.Width.addEntityDataIfNotDefaultValue(scale + 0.005f, cachedInteractionValues);
|
||||
InteractionEntityData.Responsive.addEntityDataIfNotDefaultValue(interactive, cachedInteractionValues);
|
||||
this.spawner = (entityIds, world, x, y, z, yaw, offset, packets, collider, aabb) -> {
|
||||
collider.accept(this.createCollider(Direction.UP, world, offset, x, y, z, entityIds[1], aabb));
|
||||
if (interactionEntity) {
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f, z - offset.z, 0, yaw,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
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);
|
||||
aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.fromInteraction(vec3d, scale, shulkerHeight), vec3d));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.UP, offset, x, y, z);
|
||||
} else if (direction == Direction.DOWN) {
|
||||
InteractionEntityData.Height.addEntityDataIfNotDefaultValue(shulkerHeight + 0.01f, cachedInteractionValues);
|
||||
InteractionEntityData.Width.addEntityDataIfNotDefaultValue(scale + 0.005f, cachedInteractionValues);
|
||||
InteractionEntityData.Responsive.addEntityDataIfNotDefaultValue(interactive, cachedInteractionValues);
|
||||
this.spawner = (entityIds, world, x, y, z, yaw, offset, packets, collider, aabb) -> {
|
||||
collider.accept(this.createCollider(Direction.DOWN, world, offset, x, y, z, entityIds[1], aabb));
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[1], List.of(ShulkerData.AttachFace.createEntityDataIfNotDefaultValue(CoreReflections.instance$Direction$UP))));
|
||||
if (interactionEntity) {
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f - shulkerHeight + scale, z - offset.z, 0, yaw,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
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);
|
||||
aabb.accept(new FurnitureHitboxPart(entityIds[2], AABB.fromInteraction(vec3d, scale, shulkerHeight), vec3d));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.DOWN, offset, x, y, z);
|
||||
} else {
|
||||
InteractionEntityData.Height.addEntityDataIfNotDefaultValue(scale + 0.01f, cachedInteractionValues);
|
||||
InteractionEntityData.Width.addEntityDataIfNotDefaultValue(scale + 0.005f, cachedInteractionValues);
|
||||
InteractionEntityData.Responsive.addEntityDataIfNotDefaultValue(interactive, cachedInteractionValues);
|
||||
this.spawner = (entityIds, world, x, y, z, yaw, offset, packets, collider, aabb) -> {
|
||||
Direction shulkerAnchor = getOriginalDirection(direction, Direction.fromYaw(yaw));
|
||||
Direction shulkerDirection = shulkerAnchor.opposite();
|
||||
collider.accept(this.createCollider(shulkerDirection, world, offset, x, y, z, entityIds[1], aabb));
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[1], List.of(ShulkerData.AttachFace.createEntityDataIfNotDefaultValue(DirectionUtils.toNMSDirection(shulkerAnchor)))));
|
||||
if (interactionEntity) {
|
||||
// first interaction
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.005f, z - offset.z, 0, yaw,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityIds[2], List.copyOf(cachedInteractionValues)));
|
||||
// second interaction
|
||||
double distance = shulkerHeight - scale;
|
||||
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityIds[3], UUID.randomUUID(), x + offset.x + shulkerDirection.stepX() * distance, y + offset.y - 0.005f, z - offset.z + shulkerDirection.stepZ() * distance, 0, yaw,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
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 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.fromInteraction(vec3d1, scale, scale), vec3d1));
|
||||
aabb.accept(new FurnitureHitboxPart(entityIds[3], AABB.fromInteraction(vec3d2, scale, scale), vec3d2));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.aabbCreator = (x, y, z, yaw, offset) -> {
|
||||
Direction shulkerAnchor = getOriginalDirection(direction, Direction.fromYaw(yaw));
|
||||
Direction shulkerDirection = shulkerAnchor.opposite();
|
||||
return createAABB(shulkerDirection, offset, x, y, z);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static float getPhysicalPeek(float peek) {
|
||||
return 0.5F - MiscUtils.sin((0.5F + peek) * 3.1415927F) * 0.5F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForPlacement(WorldPosition targetPos, Consumer<AABB> aabbConsumer) {
|
||||
if (this.blocksBuilding) {
|
||||
Quaternionf conjugated = QuaternionUtils.toQuaternionf(0f, (float) Math.toRadians(180 - targetPos.yRot()), 0f).conjugate();
|
||||
Vector3f offset = conjugated.transform(new Vector3f(position()));
|
||||
aabbConsumer.accept(this.aabbCreator.create(targetPos.x, targetPos.y, targetPos.z, targetPos.yRot, offset));
|
||||
}
|
||||
}
|
||||
|
||||
public float scale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public byte peek() {
|
||||
return peek;
|
||||
}
|
||||
|
||||
public boolean interactive() {
|
||||
return interactive;
|
||||
}
|
||||
|
||||
public boolean interactionEntity() {
|
||||
return interactionEntity;
|
||||
}
|
||||
|
||||
public Direction direction() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShulkerFurnitureHitbox create(Furniture furniture) {
|
||||
return new ShulkerFurnitureHitbox(furniture, this);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AABBCreator {
|
||||
|
||||
AABB create(double x, double y, double z, float yaw, Vector3f offset);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DirectionalShulkerSpawner {
|
||||
|
||||
void accept(int[] entityIds,
|
||||
World world,
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
float yaw,
|
||||
Vector3f offset,
|
||||
Consumer<Object> packets,
|
||||
Consumer<Collider> collider,
|
||||
Consumer<FurnitureHitboxPart> aabb);
|
||||
}
|
||||
|
||||
public Collider createCollider(Direction direction, World world,
|
||||
Vector3f offset, double x, double y, double z,
|
||||
int entityId,
|
||||
Consumer<FurnitureHitboxPart> aabb) {
|
||||
AABB ceAABB = createAABB(direction, offset, x, y, z);
|
||||
Object level = world.serverWorld();
|
||||
Object nmsAABB = FastNMS.INSTANCE.constructor$AABB(ceAABB.minX, ceAABB.minY, ceAABB.minZ, ceAABB.maxX, ceAABB.maxY, ceAABB.maxZ);
|
||||
aabb.accept(new FurnitureHitboxPart(entityId, ceAABB, new Vec3d(x, y, z)));
|
||||
return new BukkitCollider(level, nmsAABB, x, y, z, this.canBeHitByProjectile(), true, this.blocksBuilding());
|
||||
}
|
||||
|
||||
public AABB createAABB(Direction direction, Vector3f relativePos, double x, double y, double z) {
|
||||
float peek = getPhysicalPeek(this.peek * 0.01F);
|
||||
double x1 = -this.scale * 0.5;
|
||||
double y1 = 0.0;
|
||||
double z1 = -this.scale * 0.5;
|
||||
double x2 = this.scale * 0.5;
|
||||
double y2 = this.scale;
|
||||
double z2 = this.scale * 0.5;
|
||||
|
||||
double dx = (double) direction.stepX() * peek * (double) this.scale;
|
||||
if (dx > 0) {
|
||||
x2 += dx;
|
||||
} else if (dx < 0) {
|
||||
x1 += dx;
|
||||
}
|
||||
double dy = (double) direction.stepY() * peek * (double) this.scale;
|
||||
if (dy > 0) {
|
||||
y2 += dy;
|
||||
} else if (dy < 0) {
|
||||
y1 += dy;
|
||||
}
|
||||
double dz = (double) direction.stepZ() * peek * (double) this.scale;
|
||||
if (dz > 0) {
|
||||
z2 += dz;
|
||||
} else if (dz < 0) {
|
||||
z1 += dz;
|
||||
}
|
||||
double minX = x + x1 + relativePos.x();
|
||||
double maxX = x + x2 + relativePos.x();
|
||||
double minY = y + y1 + relativePos.y();
|
||||
double maxY = y + y2 + relativePos.y();
|
||||
double minZ = z + z1 - relativePos.z();
|
||||
double maxZ = z + z2 - relativePos.z();
|
||||
return new AABB(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
public static Direction getOriginalDirection(Direction newDirection, Direction oldDirection) {
|
||||
switch (newDirection) {
|
||||
case NORTH -> {
|
||||
return switch (oldDirection) {
|
||||
case NORTH -> Direction.NORTH;
|
||||
case SOUTH -> Direction.SOUTH;
|
||||
case WEST -> Direction.EAST;
|
||||
case EAST -> Direction.WEST;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + oldDirection);
|
||||
};
|
||||
}
|
||||
case SOUTH -> {
|
||||
return switch (oldDirection) {
|
||||
case SOUTH -> Direction.NORTH;
|
||||
case WEST -> Direction.WEST;
|
||||
case EAST -> Direction.EAST;
|
||||
case NORTH -> Direction.SOUTH;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + oldDirection);
|
||||
};
|
||||
}
|
||||
case WEST -> {
|
||||
return switch (oldDirection) {
|
||||
case SOUTH -> Direction.EAST;
|
||||
case WEST -> Direction.NORTH;
|
||||
case EAST -> Direction.SOUTH;
|
||||
case NORTH -> Direction.WEST;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + oldDirection);
|
||||
};
|
||||
}
|
||||
case EAST -> {
|
||||
return switch (oldDirection) {
|
||||
case SOUTH -> Direction.WEST;
|
||||
case WEST -> Direction.SOUTH;
|
||||
case EAST -> Direction.NORTH;
|
||||
case NORTH -> Direction.EAST;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + oldDirection);
|
||||
};
|
||||
}
|
||||
default -> throw new IllegalStateException("Unexpected value: " + newDirection);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory implements FurnitureHitBoxConfigFactory<ShulkerFurnitureHitbox> {
|
||||
|
||||
@Override
|
||||
public ShulkerFurnitureHitboxConfig create(Map<String, Object> arguments) {
|
||||
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 = ResourceConfigUtils.getAsEnum(arguments.get("direction"), Direction.class, Direction.UP);
|
||||
boolean interactive = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("interactive", true), "interactive");
|
||||
boolean interactionEntity = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("interaction-entity", true), "interaction-entity");
|
||||
boolean canUseItemOn = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("can-use-item-on", true), "can-use-item-on");
|
||||
boolean canBeHitByProjectile = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("can-be-hit-by-projectile", true), "can-be-hit-by-projectile");
|
||||
boolean blocksBuilding = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blocks-building", true), "blocks-building");
|
||||
return new ShulkerFurnitureHitboxConfig(
|
||||
SeatConfig.fromObj(arguments.get("seats")),
|
||||
position,
|
||||
canUseItemOn, blocksBuilding, canBeHitByProjectile,
|
||||
scale, peek, interactive, interactionEntity, directionEnum
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,11 @@ import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.EventUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureDataAccessor;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureVariant;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBox;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
@@ -28,7 +26,10 @@ import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.craftengine.core.util.Cancellable;
|
||||
import net.momirealms.craftengine.core.util.ItemUtils;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
|
||||
@@ -60,6 +60,7 @@ import net.momirealms.craftengine.core.advancement.network.AdvancementHolder;
|
||||
import net.momirealms.craftengine.core.advancement.network.AdvancementProgress;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBox;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import net.momirealms.craftengine.core.entity.seat.Seat;
|
||||
import net.momirealms.craftengine.core.font.FontManager;
|
||||
@@ -358,8 +359,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
registerNMSPacketConsumer(new EntityEventListener(), NetworkReflections.clazz$ClientboundEntityEventPacket);
|
||||
registerNMSPacketConsumer(new MovePosAndRotateEntityListener(), NetworkReflections.clazz$ClientboundMoveEntityPacket$PosRot);
|
||||
registerNMSPacketConsumer(new MovePosEntityListener(), NetworkReflections.clazz$ClientboundMoveEntityPacket$Pos);
|
||||
registerNMSPacketConsumer(new RotateHeadListener(), NetworkReflections.clazz$ClientboundRotateHeadPacket);
|
||||
registerNMSPacketConsumer(new SetEntityMotionListener(), NetworkReflections.clazz$ClientboundSetEntityMotionPacket);
|
||||
registerNMSPacketConsumer(new FinishConfigurationListener(), NetworkReflections.clazz$ClientboundFinishConfigurationPacket);
|
||||
registerNMSPacketConsumer(new LoginFinishedListener(), NetworkReflections.clazz$ClientboundLoginFinishedPacket);
|
||||
registerNMSPacketConsumer(new UpdateTagsListener(), NetworkReflections.clazz$ClientboundUpdateTagsPacket);
|
||||
@@ -1765,43 +1764,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
}
|
||||
}
|
||||
|
||||
public static class RotateHeadListener implements NMSPacketListener {
|
||||
|
||||
@Override
|
||||
public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
int entityId;
|
||||
try {
|
||||
entityId = (int) NetworkReflections.methodHandle$ClientboundRotateHeadPacket$entityIdGetter.invokeExact(packet);
|
||||
} catch (Throwable t) {
|
||||
CraftEngine.instance().logger().warn("Failed to get entity id from ClientboundRotateHeadPacket", t);
|
||||
return;
|
||||
}
|
||||
if (BukkitFurnitureManager.instance().isFurnitureMetaEntity(entityId)) {
|
||||
System.out.println("RotateHeadListener");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SetEntityMotionListener implements NMSPacketListener {
|
||||
|
||||
@Override
|
||||
public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
if (!VersionHelper.isOrAbove1_21_6()) return;
|
||||
int entityId;
|
||||
try {
|
||||
entityId = (int) NetworkReflections.methodHandle$ClientboundSetEntityMotionPacket$idGetter.invokeExact(packet);
|
||||
} catch (Throwable t) {
|
||||
CraftEngine.instance().logger().warn("Failed to get entity id from ClientboundSetEntityMotionPacket", t);
|
||||
return;
|
||||
}
|
||||
if (BukkitFurnitureManager.instance().isFurnitureMetaEntity(entityId)) {
|
||||
System.out.println("SetEntityMotionListener");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FinishConfigurationListener implements NMSPacketListener {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -3726,11 +3688,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
// 先检查碰撞箱部分是否存在
|
||||
FurnitureHitBox hitBox = furniture.hitboxByEntityId(entityId);
|
||||
if (hitBox == null) return;
|
||||
Vec3d pos = hitBox.position();
|
||||
|
||||
// 检查玩家是否能破坏此点
|
||||
if (!serverPlayer.canInteractPoint(pos, 16d)) {
|
||||
return;
|
||||
for (FurnitureHitboxPart part : hitBox.parts()) {
|
||||
if (part.entityId() == entityId) {
|
||||
// 检查玩家是否能破坏此点
|
||||
if (!serverPlayer.canInteractPoint(part.pos(), 16d)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FurnitureAttemptBreakEvent preBreakEvent = new FurnitureAttemptBreakEvent(serverPlayer.platformPlayer(), furniture);
|
||||
@@ -3787,10 +3751,18 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
// 先检查碰撞箱部分是否存在
|
||||
FurnitureHitBox hitBox = furniture.hitboxByEntityId(entityId);
|
||||
if (hitBox == null) return;
|
||||
Vec3d pos = hitBox.position();
|
||||
|
||||
// 检测距离
|
||||
if (!serverPlayer.canInteractPoint(pos, 16d)) {
|
||||
FurnitureHitboxPart part = null;
|
||||
for (FurnitureHitboxPart p : hitBox.parts()) {
|
||||
if (p.entityId() == entityId) {
|
||||
Vec3d pos = p.pos();
|
||||
// 检测距离
|
||||
if (!serverPlayer.canInteractPoint(pos, 16d)) {
|
||||
return;
|
||||
}
|
||||
part = p;
|
||||
}
|
||||
}
|
||||
if (part == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3799,7 +3771,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
Vector direction = eyeLocation.getDirection();
|
||||
Location endLocation = eyeLocation.clone();
|
||||
endLocation.add(direction.multiply(serverPlayer.getCachedInteractionRange()));
|
||||
Optional<EntityHitResult> result = hitBox.clip(LocationUtils.toVec3d(eyeLocation), LocationUtils.toVec3d(endLocation));
|
||||
Optional<EntityHitResult> result = part.aabb().clip(LocationUtils.toVec3d(eyeLocation), LocationUtils.toVec3d(endLocation));
|
||||
if (result.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,9 +33,4 @@ public class FurniturePacketHandler implements EntityPacketHandler {
|
||||
public void handleMove(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMoveAndRotate(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ 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.hitbox.FurnitureHitBox;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitboxPart;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.entity.seat.Seat;
|
||||
import net.momirealms.craftengine.core.plugin.entityculling.CullingData;
|
||||
@@ -24,13 +25,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class Furniture implements Cullable {
|
||||
public final FurnitureConfig config;
|
||||
public final FurnitureDataAccessor dataAccessor;
|
||||
public final WeakReference<Entity> metaDataEntity;
|
||||
public final Entity metaDataEntity;
|
||||
|
||||
protected CullingData cullingData;
|
||||
protected FurnitureVariant currentVariant;
|
||||
@@ -44,11 +44,11 @@ public abstract class Furniture implements Cullable {
|
||||
protected Furniture(Entity metaDataEntity, FurnitureDataAccessor data, FurnitureConfig config) {
|
||||
this.config = config;
|
||||
this.dataAccessor = data;
|
||||
this.metaDataEntity = new WeakReference<>(metaDataEntity);
|
||||
this.metaDataEntity = metaDataEntity;
|
||||
this.setVariant(config.getVariant(data));
|
||||
}
|
||||
|
||||
public WeakReference<Entity> metaDataEntity() {
|
||||
public Entity metaDataEntity() {
|
||||
return this.metaDataEntity;
|
||||
}
|
||||
|
||||
@@ -75,11 +75,11 @@ public abstract class Furniture implements Cullable {
|
||||
for (int i = 0; i < furnitureHitBoxConfigs.length; i++) {
|
||||
FurnitureHitBox hitbox = furnitureHitBoxConfigs[i].create(this);
|
||||
this.hitboxes[i] = hitbox;
|
||||
for (int hitboxEntityId : hitbox.virtualEntityIds()) {
|
||||
this.hitboxMap.put(hitboxEntityId, hitbox);
|
||||
for (FurnitureHitboxPart part : hitbox.parts()) {
|
||||
this.hitboxMap.put(part.entityId(), hitbox);
|
||||
virtualEntityIds.add(part.entityId());
|
||||
}
|
||||
colliders.addAll(hitbox.colliders());
|
||||
hitbox.collectVirtualEntityIds(virtualEntityIds::addLast);
|
||||
}
|
||||
// 虚拟碰撞箱的实体id
|
||||
this.virtualEntityIds = virtualEntityIds.toIntArray();
|
||||
@@ -122,9 +122,7 @@ public abstract class Furniture implements Cullable {
|
||||
}
|
||||
|
||||
public UUID uuid() {
|
||||
Entity entity = this.metaDataEntity.get();
|
||||
if (entity == null) return null;
|
||||
return entity.uuid();
|
||||
return this.metaDataEntity.uuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,9 +156,7 @@ public abstract class Furniture implements Cullable {
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
Entity entity = this.metaDataEntity.get();
|
||||
if (entity == null) return false;
|
||||
return entity.isValid();
|
||||
return this.metaDataEntity.isValid();
|
||||
}
|
||||
|
||||
public abstract void destroy();
|
||||
@@ -178,15 +174,11 @@ public abstract class Furniture implements Cullable {
|
||||
}
|
||||
|
||||
public WorldPosition position() {
|
||||
Entity entity = this.metaDataEntity.get();
|
||||
if (entity == null) return null;
|
||||
return entity.position();
|
||||
return this.metaDataEntity.position();
|
||||
}
|
||||
|
||||
public int entityId() {
|
||||
Entity entity = this.metaDataEntity.get();
|
||||
if (entity == null) return -1;
|
||||
return entity.entityID();
|
||||
return this.metaDataEntity.entityID();
|
||||
}
|
||||
|
||||
public Vec3d getRelativePosition(Vector3f position) {
|
||||
@@ -200,8 +192,6 @@ public abstract class Furniture implements Cullable {
|
||||
}
|
||||
|
||||
public World world() {
|
||||
Entity entity = this.metaDataEntity.get();
|
||||
if (entity == null) return null;
|
||||
return entity.world();
|
||||
return this.metaDataEntity.world();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.plugin.context.Context;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.plugin.entityculling.CullingData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -7,7 +7,6 @@ import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.plugin.context.Context;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.plugin.entityculling.CullingData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -6,25 +6,17 @@ import net.momirealms.craftengine.core.entity.seat.Seat;
|
||||
import net.momirealms.craftengine.core.entity.seat.SeatOwner;
|
||||
import net.momirealms.craftengine.core.world.EntityHitResult;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface FurnitureHitBox extends SeatOwner {
|
||||
|
||||
Vec3d position();
|
||||
|
||||
Seat<FurnitureHitBox>[] seats();
|
||||
|
||||
AABB[] aabb();
|
||||
|
||||
List<Collider> colliders();
|
||||
|
||||
int[] virtualEntityIds();
|
||||
|
||||
void collectVirtualEntityIds(Consumer<Integer> collector);
|
||||
List<FurnitureHitboxPart> parts();
|
||||
|
||||
void show(Player player);
|
||||
|
||||
@@ -33,8 +25,8 @@ public interface FurnitureHitBox extends SeatOwner {
|
||||
FurnitureHitBoxConfig<?> config();
|
||||
|
||||
default Optional<EntityHitResult> clip(Vec3d min, Vec3d max) {
|
||||
for (AABB value : aabb()) {
|
||||
Optional<EntityHitResult> clip = value.clip(min, max);
|
||||
for (FurnitureHitboxPart value : parts()) {
|
||||
Optional<EntityHitResult> clip = value.aabb().clip(min, max);
|
||||
if (clip.isPresent()) {
|
||||
return clip;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture.hitbox;
|
||||
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
|
||||
public record FurnitureHitboxPart(int entityId, AABB aabb, Vec3d pos) {
|
||||
}
|
||||
Reference in New Issue
Block a user