9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 04:46:37 +00:00

添加染色家具支持

This commit is contained in:
XiaoMoMi
2025-05-11 20:22:22 +08:00
parent 2d8eb48d51
commit 1b8dabb9e9
14 changed files with 119 additions and 53 deletions

View File

@@ -10,9 +10,10 @@ import net.momirealms.craftengine.core.entity.furniture.AbstractFurnitureElement
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldPosition;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@@ -22,7 +23,7 @@ import java.util.UUID;
import java.util.function.Consumer;
public class BukkitFurnitureElement extends AbstractFurnitureElement {
private List<Object> cachedValues;
private final List<Object> commonValues;
public BukkitFurnitureElement(Key item,
Billboard billboard,
@@ -30,35 +31,40 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
Vector3f scale,
Vector3f translation,
Vector3f offset,
Quaternionf rotation) {
super(item, billboard, transform, scale, translation, offset, rotation);
Quaternionf rotation,
boolean applyDyedColor) {
super(item, billboard, transform, scale, translation, offset, rotation, applyDyedColor);
this.commonValues = new ArrayList<>();
ItemDisplayEntityData.Scale.addEntityDataIfNotDefaultValue(scale(), this.commonValues);
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(rotation(), this.commonValues);
ItemDisplayEntityData.BillboardConstraints.addEntityDataIfNotDefaultValue(billboard().id(), this.commonValues);
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(translation(), this.commonValues);
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(transform().id(), this.commonValues);
}
@Override
public void initPackets(int entityId, World world, double x, double y, double z, float yaw, Quaternionf conjugated, Consumer<Object> packets) {
public void initPackets(int entityId, @NotNull WorldPosition position, @NotNull Quaternionf conjugated, Integer dyedColor, Consumer<Object> packets) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId, UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
entityId, UUID.randomUUID(), position.x() + offset.x, position.y() + offset.y, position.z() - offset.z, 0, position.xRot(),
Reflections.instance$EntityType$ITEM_DISPLAY, 0, Reflections.instance$Vec3$Zero, 0
));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues()));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues(dyedColor)));
}
private synchronized List<Object> getCachedValues() {
if (this.cachedValues == null) {
this.cachedValues = new ArrayList<>();
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(item(), null);
if (item == null) {
CraftEngine.instance().logger().warn("Failed to create furniture element for " + item() + " because item " + item() + " not found");
item = BukkitItemManager.instance().wrap(new ItemStack(Material.STONE));
private synchronized List<Object> getCachedValues(Integer color) {
List<Object> cachedValues = new ArrayList<>(this.commonValues);
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(item(), null);
if (item == null) {
CraftEngine.instance().debug(() -> "Failed to create furniture element because item " + item() + " not found");
item = BukkitItemManager.instance().wrap(new ItemStack(Material.BARRIER));
} else {
if (color != null) {
item.dyedColor(color);
item.load();
}
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), this.cachedValues);
ItemDisplayEntityData.Scale.addEntityDataIfNotDefaultValue(scale(), this.cachedValues);
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(rotation(), this.cachedValues);
ItemDisplayEntityData.BillboardConstraints.addEntityDataIfNotDefaultValue(billboard().id(), this.cachedValues);
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(translation(), this.cachedValues);
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(transform().id(), this.cachedValues);
}
return this.cachedValues;
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), cachedValues);
return cachedValues;
}
}

View File

@@ -151,7 +151,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
MiscUtils.getAsVector3f(element.getOrDefault("scale", "1"), "scale"),
MiscUtils.getAsVector3f(element.getOrDefault("translation", "0"), "translation"),
MiscUtils.getAsVector3f(element.getOrDefault("position", "0"), "position"),
MiscUtils.getAsQuaternionf(element.getOrDefault("rotation", "0"), "rotation")
MiscUtils.getAsQuaternionf(element.getOrDefault("rotation", "0"), "rotation"),
(boolean) element.getOrDefault("apply-dyed-color", true)
);
elements.add(furnitureElement);
}

View File

@@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.util.QuaternionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
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.bukkit.Location;
import org.bukkit.attribute.Attribute;
@@ -94,10 +95,12 @@ public class LoadedFurniture implements Furniture {
List<Collider> colliders = new ArrayList<>();
World world = world();
WorldPosition position = new WorldPosition(world, x, y, z, yaw, 0);
Integer dyedColor = this.extraData.dyedColor().orElse(null);
for (FurnitureElement element : placement.elements()) {
int entityId = Reflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
fakeEntityIds.add(entityId);
element.initPackets(entityId, world, x, y, z, yaw, conjugated, packet -> {
element.initPackets(entityId, position, conjugated, dyedColor, packet -> {
packets.add(packet);
if (this.minimized) minimizedPackets.add(packet);
});
@@ -109,7 +112,7 @@ public class LoadedFurniture implements Furniture {
mainEntityIds.add(entityId);
this.hitBoxes.put(entityId, hitBox);
}
hitBox.initPacketsAndColliders(ids, world, x, y, z, yaw, conjugated, (packet, canBeMinimized) -> {
hitBox.initPacketsAndColliders(ids, position, conjugated, (packet, canBeMinimized) -> {
packets.add(packet);
if (this.minimized && !canBeMinimized) {
minimizedPackets.add(packet);

View File

@@ -9,7 +9,7 @@ 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.World;
import net.momirealms.craftengine.core.world.WorldPosition;
import net.momirealms.craftengine.core.world.collision.AABB;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
@@ -51,11 +51,11 @@ public class CustomHitBox extends AbstractHitBox {
}
@Override
public void initPacketsAndColliders(int[] entityId, World world, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
public void initPacketsAndColliders(int[] entityId, WorldPosition position, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
try {
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
entityId[0], UUID.randomUUID(), position.x() + offset.x, position.y() + offset.y, position.z() - offset.z, 0, position.xRot(),
FastNMS.INSTANCE.toNMSEntityType(this.entityType), 0, Reflections.instance$Vec3$Zero, 0
), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId[0], List.copyOf(this.cachedValues)), true);

View File

@@ -4,7 +4,7 @@ import net.momirealms.craftengine.core.entity.furniture.*;
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.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;
@@ -33,7 +33,7 @@ public class HappyGhastHitBox extends AbstractHitBox {
}
@Override
public void initPacketsAndColliders(int[] entityId, World world, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
public void initPacketsAndColliders(int[] entityId, WorldPosition position, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
}
@Override

View File

@@ -9,7 +9,7 @@ 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.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;
@@ -53,8 +53,12 @@ public class InteractionHitBox extends AbstractHitBox {
}
@Override
public void initPacketsAndColliders(int[] entityId, World world, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
public void initPacketsAndColliders(int[] entityId, WorldPosition position, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
double x = position.x();
double y = position.y();
double z = position.z();
float yaw = position.xRot();
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
Reflections.instance$EntityType$INTERACTION, 0, Reflections.instance$Vec3$Zero, 0
@@ -66,7 +70,7 @@ public class InteractionHitBox extends AbstractHitBox {
if (blocksBuilding() || this.canBeHitByProjectile()) {
AABB ceAABB = AABB.fromInteraction(new Vec3d(x + offset.x, y + offset.y, z - offset.z), this.size.x, this.size.y);
Object nmsAABB = FastNMS.INSTANCE.constructor$AABB(ceAABB.minX, ceAABB.minY, ceAABB.minZ, ceAABB.maxX, ceAABB.maxY, ceAABB.maxZ);
collider.accept(new BukkitCollider(world.serverWorld(), nmsAABB, x, y, z, this.canBeHitByProjectile(), false, this.blocksBuilding()));
collider.accept(new BukkitCollider(position.world().serverWorld(), nmsAABB, x, y, z, this.canBeHitByProjectile(), false, this.blocksBuilding()));
}
}

View File

@@ -10,6 +10,7 @@ import net.momirealms.craftengine.core.entity.furniture.*;
import net.momirealms.craftengine.core.util.*;
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;
@@ -196,9 +197,13 @@ public class ShulkerHitBox extends AbstractHitBox {
}
@Override
public void initPacketsAndColliders(int[] entityIds, World world, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
public void initPacketsAndColliders(int[] entityIds, WorldPosition position, Quaternionf conjugated, BiConsumer<Object, Boolean> packets, Consumer<Collider> collider, BiConsumer<Integer, AABB> aabb) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
try {
double x = position.x();
double y = position.y();
double z = position.z();
float yaw = position.xRot();
double originalY = y + offset.y;
double integerPart = Math.floor(originalY);
double fractionalPart = originalY - integerPart;
@@ -228,7 +233,7 @@ public class ShulkerHitBox extends AbstractHitBox {
Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, this.scale);
packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[1], Collections.singletonList(attributeInstance)), false);
}
this.spawner.accept(entityIds, world, x, y, z, yaw, offset, packets, collider, aabb);
this.spawner.accept(entityIds, position.world(), x, y, z, yaw, offset, packets, collider, aabb);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to construct shulker hitbox spawn packet", e);
}

View File

@@ -134,7 +134,7 @@ public class FurnitureItemBehavior extends ItemBehavior {
FurnitureExtraData.builder()
.item(item.copyWithCount(1))
.anchorType(anchorType)
.dyedColor(item.dyedColor().orElse(-1))
.dyedColor(item.dyedColor().orElse(null))
.build(), false);
FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, loadedFurniture, furnitureLocation, context.getHand());

View File

@@ -13,7 +13,7 @@ public class LocationUtils {
private LocationUtils() {}
public static Location toLocation(WorldPosition position) {
return new Location((World) position.world().platformWorld(), position.position().x(), position.position().y(), position.position().z());
return new Location((World) position.world().platformWorld(), position.x(), position.y(), position.z(), position.xRot(), position.yRot());
}
public static Vec3d toVec3d(Location loc) {
@@ -33,11 +33,7 @@ public class LocationUtils {
}
public static Object above(Object blockPos) throws ReflectiveOperationException {
return toBlockPos(
FastNMS.INSTANCE.field$Vec3i$x(blockPos),
FastNMS.INSTANCE.field$Vec3i$y(blockPos) + 1,
FastNMS.INSTANCE.field$Vec3i$z(blockPos)
);
return toBlockPos(FastNMS.INSTANCE.field$Vec3i$x(blockPos), FastNMS.INSTANCE.field$Vec3i$y(blockPos) + 1, FastNMS.INSTANCE.field$Vec3i$z(blockPos));
}
public static Object toBlockPos(int x, int y, int z) {