9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-29 11:59:11 +00:00

add minimized option

This commit is contained in:
XiaoMoMi
2025-04-01 02:25:21 +08:00
parent bb347b1311
commit 61762e314d
9 changed files with 60 additions and 23 deletions

View File

@@ -285,7 +285,7 @@ public class BukkitFurnitureManager implements FurnitureManager {
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
for (Player player : display.getTrackedPlayers()) {
this.plugin.adapt(player).furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket());
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket(player));
}
}
}

View File

@@ -13,10 +13,7 @@ import net.momirealms.craftengine.core.util.QuaternionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.Location;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.*;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.joml.Quaternionf;
@@ -41,11 +38,13 @@ public class LoadedFurniture {
private final List<Integer> fakeEntityIds;
private final List<Integer> hitBoxEntityIds;
private final Map<Integer, HitBox> hitBoxes;
private final boolean minimized;
// seats
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
private final Vector<Entity> seats = new Vector<>();
// cached spawn packet
private Object cachedSpawnPacket;
private Object cachedMinimizedSpawnPacket;
public LoadedFurniture(Entity baseEntity,
CustomFurniture furniture,
@@ -57,6 +56,7 @@ public class LoadedFurniture {
this.baseEntity = new WeakReference<>(baseEntity);
this.furniture = furniture;
this.hitBoxes = new HashMap<>();
this.minimized = furniture.settings().minimized();
List<Integer> fakeEntityIds = new ArrayList<>();
List<Integer> hitBoxEntityIds = new ArrayList<>();
CustomFurniture.Placement placement = furniture.getPlacement(anchorType);
@@ -70,22 +70,34 @@ public class LoadedFurniture {
float yaw = this.location.getYaw();
List<Object> packets = new ArrayList<>();
List<Object> minimizedPackets = new ArrayList<>();
for (FurnitureElement element : placement.elements()) {
int entityId = Reflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
fakeEntityIds.add(entityId);
element.addSpawnPackets(entityId, x, y, z, yaw, conjugated, packets::add);
element.addSpawnPackets(entityId, x, y, z, yaw, conjugated, packet -> {
packets.add(packet);
if (this.minimized) minimizedPackets.add(packet);
});
}
for (HitBox hitBox : placement.hitBoxes()) {
int[] ids = hitBox.acquireEntityIds(Reflections.instance$Entity$ENTITY_COUNTER::incrementAndGet);
for (int entityId : ids) {
fakeEntityIds.add(entityId);
hitBoxEntityIds.add(entityId);
hitBox.addSpawnPackets(ids, x, y, z, yaw, conjugated, packets::add);
hitBox.addSpawnPackets(ids, x, y, z, yaw, conjugated, (packet, canBeMinimized) -> {
packets.add(packet);
if (this.minimized && !canBeMinimized) {
minimizedPackets.add(packet);
}
});
this.hitBoxes.put(entityId, hitBox);
}
}
try {
this.cachedSpawnPacket = Reflections.constructor$ClientboundBundlePacket.newInstance(packets);
if (this.minimized) {
this.cachedMinimizedSpawnPacket = Reflections.constructor$ClientboundBundlePacket.newInstance(minimizedPackets);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to init spawn packets for furniture " + id, e);
}
@@ -114,8 +126,13 @@ public class LoadedFurniture {
}
@NotNull
public Object spawnPacket() {
return this.cachedSpawnPacket;
public Object spawnPacket(Player player) {
// TODO hasPermission might be slow, can we use a faster way in the future?
if (!this.minimized || player.hasPermission(FurnitureManager.FURNITURE_ADMIN_NODE)) {
return this.cachedSpawnPacket;
} else {
return this.cachedMinimizedSpawnPacket;
}
}
@NotNull

View File

@@ -7,6 +7,7 @@ import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -29,7 +30,7 @@ public class HappyGhastHitBox extends AbstractHitBox {
}
@Override
public void addSpawnPackets(int[] entityId, double x, double y, double z, float yaw, Quaternionf conjugated, Consumer<Object> packets) {
public void addSpawnPackets(int[] entityId, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets) {
// todo 乐魂
}

View File

@@ -12,6 +12,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -46,14 +47,14 @@ public class InteractionHitBox extends AbstractHitBox {
}
@Override
public void addSpawnPackets(int[] entityId, double x, double y, double z, float yaw, Quaternionf conjugated, Consumer<Object> packets) {
public void addSpawnPackets(int[] entityId, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
try {
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
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
));
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityId[0], List.copyOf(this.cachedValues)));
), true);
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityId[0], List.copyOf(this.cachedValues)), true);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to construct hitbox spawn packet", e);
}

View File

@@ -14,6 +14,7 @@ import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -90,30 +91,30 @@ public class ShulkerHitBox extends AbstractHitBox {
}
@Override
public void addSpawnPackets(int[] entityIds, double x, double y, double z, float yaw, Quaternionf conjugated, Consumer<Object> packets) {
public void addSpawnPackets(int[] entityIds, double x, double y, double z, float yaw, Quaternionf conjugated, BiConsumer<Object, Boolean> packets) {
Vector3f offset = conjugated.transform(new Vector3f(position()));
try {
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
entityIds[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
Reflections.instance$EntityType$ITEM_DISPLAY, 0, Reflections.instance$Vec3$Zero, 0
));
), false);
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
entityIds[1], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
Reflections.instance$EntityType$SHULKER, 0, Reflections.instance$Vec3$Zero, 0
));
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityIds[1], List.copyOf(this.cachedShulkerValues)));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetPassengersPacket(entityIds[0], entityIds[1]));
), false);
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityIds[1], List.copyOf(this.cachedShulkerValues)), false);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetPassengersPacket(entityIds[0], entityIds[1]), false);
if (VersionHelper.isVersionNewerThan1_20_5()) {
Object attributeInstance = Reflections.constructor$AttributeInstance.newInstance(Reflections.instance$Holder$Attribute$scale, (Consumer<?>) (o) -> {});
Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, scale);
packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[1], Collections.singletonList(attributeInstance)));
packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[1], Collections.singletonList(attributeInstance)), false);
}
if (this.interactionEntity) {
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
entityIds[2], UUID.randomUUID(), x + offset.x, y + offset.y - 0.0005f, z - offset.z, 0, yaw,
Reflections.instance$EntityType$INTERACTION, 0, Reflections.instance$Vec3$Zero, 0
));
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityIds[2], List.copyOf(this.cachedInteractionValues)));
), true);
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityIds[2], List.copyOf(this.cachedInteractionValues)), true);
}
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to construct shulker hitbox spawn packet", e);

View File

@@ -619,7 +619,7 @@ public class PacketConsumers {
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(entityId);
if (furniture != null) {
user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
user.sendPacket(furniture.spawnPacket(), false);
user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false);
if (ConfigManager.hideBaseEntity()) {
event.setCancelled(true);
}