diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml b/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml index 26254e70f..05578bdbc 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml @@ -33,6 +33,7 @@ items: type: shulker direction: east peek: 100 + blocks-building: true interactive: true interaction-entity: true seats: @@ -71,14 +72,20 @@ items: rotation: -90 hitboxes: - position: 0,0,0 + type: interaction + blocks-building: true width: 0.7 height: 0.1 interactive: true - position: 0,0.1,-0.1 + type: interaction + blocks-building: true width: 0.1 height: 0.6 interactive: true - position: 0,0.6,0.15 + type: interaction + blocks-building: true width: 0.4 height: 0.4 interactive: true @@ -114,6 +121,8 @@ items: translation: 0,0.5,0 hitboxes: - position: 0,0,0 + type: interaction + blocks-building: true width: 0.7 height: 1.2 interactive: true diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java index 72588c70a..264fa2b6e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java @@ -80,13 +80,12 @@ public class LoadedFurniture implements Furniture { hasExternalModel = false; } - double yawInRadius = Math.toRadians(180 - this.location.getYaw()); - Quaternionf conjugated = QuaternionUtils.toQuaternionf(0, yawInRadius, 0).conjugate(); + float yaw = this.location.getYaw(); + Quaternionf conjugated = QuaternionUtils.toQuaternionf(0, Math.toRadians(180 - yaw), 0).conjugate(); double x = location.getX(); double y = location.getY(); double z = location.getZ(); - float yaw = this.location.getYaw(); List packets = new ArrayList<>(); List minimizedPackets = new ArrayList<>(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java index e742a7ecf..08126740d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java @@ -67,6 +67,10 @@ public class CustomHitBox extends AbstractHitBox { } } + @Override + public void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs) { + } + @Override public int[] acquireEntityIds(Supplier entityIdSupplier) { return new int[] {entityIdSupplier.get()}; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java index 32d3460ce..571f126d4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java @@ -33,7 +33,10 @@ public class HappyGhastHitBox extends AbstractHitBox { @Override public void initPacketsAndColliders(int[] entityId, World world, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer packets, Consumer collider, BiConsumer aabb) { - // todo 乐魂 + } + + @Override + public void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs) { } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java index 4245aaa46..8d1c04e7e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java @@ -72,6 +72,15 @@ public class InteractionHitBox extends AbstractHitBox { } } + @Override + public void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs) { + if (blocksBuilding()) { + Vector3f offset = conjugated.transform(new Vector3f(position())); + AABB ceAABB = AABB.fromInteraction(new Vec3d(x + offset.x, y + offset.y, z - offset.z), this.size.x, this.size.y); + aabbs.accept(ceAABB); + } + } + @Override public int[] acquireEntityIds(Supplier entityIdSupplier) { return new int[] {entityIdSupplier.get()}; @@ -95,7 +104,7 @@ public class InteractionHitBox extends AbstractHitBox { boolean canUseOn = (boolean) arguments.getOrDefault("can-use-item-on", false); boolean interactive = (boolean) arguments.getOrDefault("interactive", true); boolean canBeHitByProjectile = (boolean) arguments.getOrDefault("can-be-hit-by-projectile", false); - boolean blocksBuilding = (boolean) arguments.getOrDefault("blocks-building", false); + boolean blocksBuilding = (boolean) arguments.getOrDefault("blocks-building", true); return new InteractionHitBox( HitBoxFactory.getSeats(arguments), position, diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java index c78a5a68e..fd2fa5be2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java @@ -29,6 +29,7 @@ public class ShulkerHitBox extends AbstractHitBox { private final Direction direction; private final List cachedShulkerValues = new ArrayList<>(); private final DirectionalShulkerSpawner spawner; + private final AABBCreator aabbCreator; public ShulkerHitBox(Seat[] seats, Vector3f position, Direction direction, float scale, byte peek, boolean interactionEntity, boolean interactive, boolean canUseOn, boolean blocksBuilding, boolean canBeHitByProjectile) { super(seats, position, canUseOn, blocksBuilding, canBeHitByProjectile); @@ -64,6 +65,7 @@ public class ShulkerHitBox extends AbstractHitBox { } } }; + this.aabbCreator = (x, y, z, yaw, offset) -> createAABB(Direction.UP, offset, x, y, z); } else if (this.direction == Direction.DOWN) { InteractionEntityData.Height.addEntityDataIfNotDefaultValue(shulkerHeight + 0.01f, cachedInteractionValues); InteractionEntityData.Width.addEntityDataIfNotDefaultValue(scale + 0.005f, cachedInteractionValues); @@ -82,6 +84,7 @@ public class ShulkerHitBox extends AbstractHitBox { } } }; + 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); @@ -111,10 +114,26 @@ public class ShulkerHitBox extends AbstractHitBox { } } }; + 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 Collider createCollider(Direction direction, World world, Vector3f offset, double x, double y, double z, int entityId, BiConsumer 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(entityId, ceAABB); + return new BukkitCollider( + FastNMS.INSTANCE.createCollisionShulker(level, nmsAABB, x, y, z, this.canBeHitByProjectile(), true, this.blocksBuilding()), + ColliderType.SHULKER + ); + } + + public AABB createAABB(Direction direction, Vector3f offset, double x, double y, double z) { float peek = getPhysicalPeek(this.peek() * 0.01F); double x1 = -this.scale * 0.5; double y1 = 0.0; @@ -141,20 +160,13 @@ public class ShulkerHitBox extends AbstractHitBox { } else if (dz < 0) { z1 += dz; } - - Object level = world.serverWorld(); double minX = x + x1 + offset.x(); double maxX = x + x2 + offset.x(); double minY = y + y1 + offset.y(); double maxY = y + y2 + offset.y(); double minZ = z + z1 - offset.z(); double maxZ = z + z2 - offset.z(); - Object nmsAABB = FastNMS.INSTANCE.constructor$AABB(minX, minY, minZ, maxX, maxY, maxZ); - aabb.accept(entityId, new AABB(minX, minY, minZ, maxX, maxY, maxZ)); - return new BukkitCollider( - FastNMS.INSTANCE.createCollisionShulker(level, nmsAABB, x, y, z, this.canBeHitByProjectile(), true, this.blocksBuilding()), - ColliderType.SHULKER - ); + return new AABB(minX, minY, minZ, maxX, maxY, maxZ); } private static float getPhysicalPeek(float peek) { @@ -225,12 +237,24 @@ public class ShulkerHitBox extends AbstractHitBox { } } + @Override + public void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs) { + Vector3f offset = conjugated.transform(new Vector3f(position())); + aabbs.accept(this.aabbCreator.create(x, y, z, yaw, offset)); + } + @FunctionalInterface interface DirectionalShulkerSpawner { void accept(int[] entityIds, World world, double x, double y, double z, float yaw, Vector3f offset, BiConsumer packets, Consumer collider, BiConsumer aabb); } + @FunctionalInterface + interface AABBCreator { + + AABB create(double x, double y, double z, float yaw, Vector3f offset); + } + @Override public int[] acquireEntityIds(Supplier entityIdSupplier) { if (this.interactionEntity) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java index 7e59d402c..3c0d02793 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java @@ -4,11 +4,13 @@ import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptPlaceEvent; import net.momirealms.craftengine.bukkit.api.event.FurniturePlaceEvent; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; +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.core.entity.furniture.AnchorType; import net.momirealms.craftengine.core.entity.furniture.CustomFurniture; +import net.momirealms.craftengine.core.entity.furniture.HitBox; import net.momirealms.craftengine.core.entity.player.InteractionResult; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.Item; @@ -17,15 +19,16 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; import net.momirealms.craftengine.core.item.context.UseOnContext; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.util.Direction; -import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.MiscUtils; -import net.momirealms.craftengine.core.util.Pair; +import net.momirealms.craftengine.core.util.*; import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.collision.AABB; import org.bukkit.Location; import org.bukkit.World; +import org.joml.Quaternionf; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Optional; @@ -102,6 +105,17 @@ public class FurnitureItemBehavior extends ItemBehavior { } Location furnitureLocation = new Location(world, finalPlacePosition.x(), finalPlacePosition.y(), finalPlacePosition.z(), (float) furnitureYaw, 0); + + List aabbs = new ArrayList<>(); + for (HitBox hitBox : placement.hitBoxes()) { + hitBox.initShapeForPlacement(finalPlacePosition.x(), finalPlacePosition.y(), finalPlacePosition.z(), (float) furnitureYaw, QuaternionUtils.toQuaternionf(0, Math.toRadians(180 - furnitureYaw), 0).conjugate(), aabbs::add); + } + if (!aabbs.isEmpty()) { + if (!FastNMS.INSTANCE.checkEntityCollision(context.getLevel().serverWorld(), aabbs.stream().map(it -> FastNMS.INSTANCE.constructor$AABB(it.minX, it.minY, it.minZ, it.maxX, it.maxY, it.maxZ)).toList(), finalPlacePosition.x(), finalPlacePosition.y(), finalPlacePosition.z())) { + return InteractionResult.FAIL; + } + } + if (!BukkitCraftEngine.instance().antiGrief().canPlace(bukkitPlayer, furnitureLocation)) { return InteractionResult.FAIL; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java index 61d9076bc..28d4208c1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java @@ -17,6 +17,8 @@ public interface HitBox { void initPacketsAndColliders(int[] entityId, World world, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer packets, Consumer collider, BiConsumer aabb); + void initShapeForPlacement(double x, double y, double z, float yaw, Quaternionf conjugated, Consumer aabbs); + int[] acquireEntityIds(Supplier entityIdSupplier); Seat[] seats(); diff --git a/gradle.properties b/gradle.properties index f2e5b2307..3ee40e227 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.49-beta.5 +project_version=0.0.49 config_version=29 lang_version=7 project_group=net.momirealms @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.15 -nms_helper_version=0.60.8 +nms_helper_version=0.60.11 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23 amazon_awssdk_eventstream_version=1.0.1