mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
家具重构part3
This commit is contained in:
@@ -185,7 +185,7 @@ public final class CraftEngineFurniture {
|
||||
*/
|
||||
@Nullable
|
||||
public static BukkitFurniture getLoadedFurnitureByBaseEntity(@NotNull Entity baseEntity) {
|
||||
return BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(baseEntity.getEntityId());
|
||||
return BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(baseEntity.getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,7 +199,7 @@ public final class CraftEngineFurniture {
|
||||
if (isSeat(seat)) {
|
||||
CompoundTag seatExtraData = BukkitSeatManager.instance().getSeatExtraData(seat);
|
||||
int entityId = seatExtraData.getInt("entity_id");
|
||||
BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
|
||||
BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(entityId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -212,7 +212,7 @@ public final class CraftEngineFurniture {
|
||||
*/
|
||||
public static boolean remove(@NotNull Entity entity) {
|
||||
if (!isFurniture(entity)) return false;
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entity.getEntityId());
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(entity.getEntityId());
|
||||
if (furniture == null) return false;
|
||||
furniture.destroy();
|
||||
return true;
|
||||
@@ -230,7 +230,7 @@ public final class CraftEngineFurniture {
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
if (!isFurniture(entity)) return false;
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entity.getEntityId());
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(entity.getEntityId());
|
||||
if (furniture == null) return false;
|
||||
remove(furniture, (net.momirealms.craftengine.core.entity.player.Player) null, dropLoot, playSound);
|
||||
return true;
|
||||
@@ -250,7 +250,7 @@ public final class CraftEngineFurniture {
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
if (!isFurniture(entity)) return false;
|
||||
Furniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entity.getEntityId());
|
||||
Furniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(entity.getEntityId());
|
||||
if (furniture == null) return false;
|
||||
remove(furniture, player, dropLoot, playSound);
|
||||
return true;
|
||||
@@ -320,7 +320,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
}
|
||||
if (playSound) {
|
||||
world.playBlockSound(position, furniture.config().settings().sounds().breakSound());
|
||||
world.playBlockSound(position, furniture.config.settings().sounds().breakSound());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ 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;
|
||||
@@ -17,23 +18,20 @@ public final class FurnitureAttemptPlaceEvent extends PlayerEvent implements Can
|
||||
private boolean cancelled;
|
||||
private final FurnitureConfig furniture;
|
||||
private final Location location;
|
||||
private final AnchorType anchorType;
|
||||
private final BlockFace clickedFace;
|
||||
private final FurnitureVariant variant;
|
||||
private final Block clickedBlock;
|
||||
private final InteractionHand hand;
|
||||
|
||||
public FurnitureAttemptPlaceEvent(@NotNull Player player,
|
||||
@NotNull FurnitureConfig furniture,
|
||||
@NotNull AnchorType anchorType,
|
||||
@NotNull FurnitureVariant variant,
|
||||
@NotNull Location location,
|
||||
@NotNull BlockFace clickedFace,
|
||||
@NotNull InteractionHand hand,
|
||||
@NotNull Block clickedBlock) {
|
||||
super(player);
|
||||
this.furniture = furniture;
|
||||
this.location = location;
|
||||
this.anchorType = anchorType;
|
||||
this.clickedFace = clickedFace;
|
||||
this.variant = variant;
|
||||
this.clickedBlock = clickedBlock;
|
||||
this.hand = hand;
|
||||
}
|
||||
@@ -48,19 +46,14 @@ public final class FurnitureAttemptPlaceEvent extends PlayerEvent implements Can
|
||||
return hand;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public BlockFace clickedFace() {
|
||||
return clickedFace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Player player() {
|
||||
return getPlayer();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnchorType anchorType() {
|
||||
return anchorType;
|
||||
public FurnitureVariant variant() {
|
||||
return variant;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -25,7 +25,6 @@ public class BukkitFurniture extends Furniture {
|
||||
super(new BukkitEntity(metaEntity), data, config);
|
||||
this.metaEntity = new WeakReference<>(metaEntity);
|
||||
this.location = metaEntity.getLocation();
|
||||
this.setVariant(super.config().getVariant(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,23 +5,20 @@ import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes;
|
||||
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.core.entity.furniture.*;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.sound.SoundData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.CEWorld;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.chunk.CEChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Interaction;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -46,7 +43,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
private final BukkitCraftEngine plugin;
|
||||
|
||||
private final Map<Integer, BukkitFurniture> byMetaEntityId = new ConcurrentHashMap<>(256, 0.5f);
|
||||
private final Map<Integer, BukkitFurniture> byEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
||||
private final Map<Integer, BukkitFurniture> byVirtualEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
||||
private final Map<Integer, BukkitFurniture> byColliderEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
||||
// Event listeners
|
||||
private final FurnitureEventListener furnitureEventListener;
|
||||
|
||||
@@ -63,31 +61,25 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
|
||||
@Override
|
||||
public Furniture place(WorldPosition position, FurnitureConfig furniture, FurnitureDataAccessor dataAccessor, boolean playSound) {
|
||||
// return this.place(LocationUtils.toLocation(position), furniture, dataAccessor, playSound);
|
||||
return null;
|
||||
return this.place(LocationUtils.toLocation(position), furniture, dataAccessor, playSound);
|
||||
}
|
||||
|
||||
public BukkitFurniture place(Location location, FurnitureConfig furniture, FurnitureDataAccessor extraData, boolean playSound) {
|
||||
// Optional<AnchorType> optionalAnchorType = extraData.anchorType();
|
||||
// if (optionalAnchorType.isEmpty() || !furniture.isAllowedPlacement(optionalAnchorType.get())) {
|
||||
// extraData.anchorType(furniture.getAnyAnchorType());
|
||||
// }
|
||||
// Entity furnitureEntity = EntityUtils.spawnEntity(location.getWorld(), location, EntityType.ITEM_DISPLAY, entity -> {
|
||||
// ItemDisplay display = (ItemDisplay) entity;
|
||||
// display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_KEY, PersistentDataType.STRING, furniture.id().toString());
|
||||
// try {
|
||||
// display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_EXTRA_DATA_KEY, PersistentDataType.BYTE_ARRAY, extraData.toBytes());
|
||||
// } catch (IOException e) {
|
||||
// this.plugin.logger().warn("Failed to set furniture PDC for " + furniture.id().toString(), e);
|
||||
// }
|
||||
// handleBaseEntityLoadEarly(display);
|
||||
// });
|
||||
// if (playSound) {
|
||||
// SoundData data = furniture.settings().sounds().placeSound();
|
||||
// location.getWorld().playSound(location, data.id().toString(), SoundCategory.BLOCKS, data.volume().get(), data.pitch().get());
|
||||
// }
|
||||
// return loadedFurnitureByRealEntityId(furnitureEntity.getEntityId());
|
||||
return null;
|
||||
public BukkitFurniture place(Location location, FurnitureConfig furniture, FurnitureDataAccessor data, boolean playSound) {
|
||||
Entity furnitureEntity = EntityUtils.spawnEntity(location.getWorld(), location, EntityType.ITEM_DISPLAY, entity -> {
|
||||
ItemDisplay display = (ItemDisplay) entity;
|
||||
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_KEY, PersistentDataType.STRING, furniture.id().toString());
|
||||
try {
|
||||
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_EXTRA_DATA_KEY, PersistentDataType.BYTE_ARRAY, data.toBytes());
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn("Failed to set furniture PDC for " + furniture.id().toString(), e);
|
||||
}
|
||||
handleMetaEntityAfterChunkLoad(display);
|
||||
});
|
||||
if (playSound) {
|
||||
SoundData sound = furniture.settings().sounds().placeSound();
|
||||
location.getWorld().playSound(location, sound.id().toString(), SoundCategory.BLOCKS, sound.volume().get(), sound.pitch().get());
|
||||
}
|
||||
return loadedFurnitureByMetaEntityId(furnitureEntity.getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,43 +130,59 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFurnitureRealEntity(int entityId) {
|
||||
public boolean isFurnitureMetaEntity(int entityId) {
|
||||
return this.byMetaEntityId.containsKey(entityId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BukkitFurniture loadedFurnitureByRealEntityId(int entityId) {
|
||||
public BukkitFurniture loadedFurnitureByMetaEntityId(int entityId) {
|
||||
return this.byMetaEntityId.get(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BukkitFurniture loadedFurnitureByEntityId(int entityId) {
|
||||
return this.byEntityId.get(entityId);
|
||||
@Override
|
||||
public BukkitFurniture loadedFurnitureByVirtualEntityId(int entityId) {
|
||||
return this.byVirtualEntityId.get(entityId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BukkitFurniture loadedFurnitureByColliderEntityId(int entityId) {
|
||||
return this.byColliderEntityId.get(entityId);
|
||||
}
|
||||
|
||||
// 当元数据实体被卸载了
|
||||
protected void handleMetaEntityUnload(Entity entity) {
|
||||
// 不是持久化的
|
||||
if (!entity.isPersistent()) {
|
||||
return;
|
||||
}
|
||||
int id = entity.getEntityId();
|
||||
BukkitFurniture furniture = this.byMetaEntityId.remove(id);
|
||||
if (furniture != null) {
|
||||
Location location = entity.getLocation();
|
||||
// 区块还在加载的时候,就重复卸载了
|
||||
// 区块还在加载的时候,就重复卸载了。为极其特殊情况
|
||||
boolean isPreventing = FastNMS.INSTANCE.method$ServerLevel$isPreventingStatusUpdates(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()), location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
if (!isPreventing) {
|
||||
furniture.destroySeats();
|
||||
}
|
||||
for (int sub : furniture.entityIds()) {
|
||||
this.byEntityId.remove(sub);
|
||||
for (int sub : furniture.virtualEntityIds()) {
|
||||
this.byVirtualEntityId.remove(sub);
|
||||
}
|
||||
for (int sub : furniture.colliderEntityIds()) {
|
||||
this.byColliderEntityId.remove(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保险起见,collision实体卸载也移除一下
|
||||
protected void handleCollisionEntityUnload(Entity entity) {
|
||||
int id = entity.getEntityId();
|
||||
this.byMetaEntityId.remove(id);
|
||||
this.byColliderEntityId.remove(id);
|
||||
}
|
||||
|
||||
// 检查这个区块的实体是否已经被加载了
|
||||
private boolean isEntitiesLoaded(Location location) {
|
||||
CEWorld ceWorld = this.plugin.worldManager().getWorld(location.getWorld());
|
||||
CEChunk ceChunk = ceWorld.getChunkAtIfLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
@@ -216,8 +224,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
BukkitFurniture previous = this.byMetaEntityId.get(entity.getEntityId());
|
||||
if (previous != null) return;
|
||||
|
||||
BukkitFurniture furniture = addNewFurniture(entity, customFurniture);
|
||||
furniture.addCollidersToWorld();
|
||||
// 创建新的家具
|
||||
createFurnitureInstance(entity, customFurniture);
|
||||
}
|
||||
|
||||
protected void handleMetaEntityAfterChunkLoad(ItemDisplay entity) {
|
||||
@@ -245,8 +253,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
BukkitFurniture previous = this.byMetaEntityId.get(entity.getEntityId());
|
||||
if (previous != null) return;
|
||||
|
||||
BukkitFurniture furniture = addNewFurniture(entity, customFurniture);
|
||||
furniture.addCollidersToWorld();
|
||||
createFurnitureInstance(entity, customFurniture);
|
||||
}
|
||||
|
||||
protected void handleCollisionEntityAfterChunkLoad(Entity entity) {
|
||||
@@ -298,17 +305,17 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized BukkitFurniture addNewFurniture(ItemDisplay display, FurnitureConfig furniture) {
|
||||
// 创建家具实例,并初始化碰撞实体
|
||||
private void createFurnitureInstance(ItemDisplay display, FurnitureConfig furniture) {
|
||||
BukkitFurniture bukkitFurniture = new BukkitFurniture(display, furniture, getFurnitureDataAccessor(display));
|
||||
this.byMetaEntityId.put(display.getEntityId(), bukkitFurniture);
|
||||
for (int entityId : bukkitFurniture.entityIds()) {
|
||||
this.byEntityId.put(entityId, bukkitFurniture);
|
||||
for (int entityId : bukkitFurniture.virtualEntityIds()) {
|
||||
this.byVirtualEntityId.put(entityId, bukkitFurniture);
|
||||
}
|
||||
for (Collider collisionEntity : bukkitFurniture.colliders()) {
|
||||
int collisionEntityId = FastNMS.INSTANCE.method$Entity$getId(collisionEntity.handle());
|
||||
this.byEntityId.put(collisionEntityId, bukkitFurniture);
|
||||
this.byColliderEntityId.put(collisionEntity.entityId(), bukkitFurniture);
|
||||
}
|
||||
return bukkitFurniture;
|
||||
bukkitFurniture.addCollidersToWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
|
||||
public record ItemColorSource(Color dyedColor, int[] fireworkColors) {
|
||||
}
|
||||
@@ -1,22 +1,61 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture.element;
|
||||
|
||||
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.MEntityTypes;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureColorSource;
|
||||
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElement;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ItemDisplayFurnitureElement implements FurnitureElement {
|
||||
private final ItemDisplayFurnitureElementConfig config;
|
||||
private final WorldPosition position;
|
||||
private final int entityId;
|
||||
private final Object despawnPacket;
|
||||
private final FurnitureColorSource colorSource;
|
||||
|
||||
public ItemDisplayFurnitureElement(ItemDisplayFurnitureElementConfig config) {
|
||||
public ItemDisplayFurnitureElement(Furniture furniture, ItemDisplayFurnitureElementConfig config) {
|
||||
this.config = config;
|
||||
this.entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
WorldPosition furniturePos = furniture.position();
|
||||
Vec3d position = Furniture.getRelativePosition(furniturePos, config.position());
|
||||
this.position = new WorldPosition(furniturePos.world, position.x, position.y, position.z, furniturePos.xRot, furniturePos.yRot);
|
||||
this.despawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(new IntArrayList() {{ add(entityId); }});
|
||||
this.colorSource = furniture.dataAccessor.getColorSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Player player) {
|
||||
|
||||
player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundBundlePacket(List.of(
|
||||
FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
this.entityId, UUID.randomUUID(),
|
||||
this.position.x, this.position.y, this.position.z, 0, this.position.yRot,
|
||||
MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
),
|
||||
FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadata.apply(player, this.colorSource))
|
||||
)), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Player player) {
|
||||
player.sendPacket(this.despawnPacket, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] virtualEntityIds() {
|
||||
return new int[] {this.entityId};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectVirtualEntityId(Consumer<Integer> collector) {
|
||||
collector.accept(this.entityId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ 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.bukkit.entity.furniture.ItemColorSource;
|
||||
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;
|
||||
@@ -28,21 +28,21 @@ import java.util.function.BiFunction;
|
||||
|
||||
public class ItemDisplayFurnitureElementConfig implements FurnitureElementConfig<ItemDisplayFurnitureElement> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final BiFunction<Player, ItemColorSource, List<Object>> lazyMetadataPacket;
|
||||
private final BiFunction<Player, ItemColorSource, Item<?>> item;
|
||||
private final Vector3f scale;
|
||||
private final Vector3f position;
|
||||
private final Vector3f translation;
|
||||
private final float xRot;
|
||||
private final float yRot;
|
||||
private final Quaternionf rotation;
|
||||
private final ItemDisplayContext displayContext;
|
||||
private final Billboard billboard;
|
||||
private final float shadowRadius;
|
||||
private final float shadowStrength;
|
||||
private final boolean applyDyedColor;
|
||||
public final BiFunction<Player, FurnitureColorSource, List<Object>> metadata;
|
||||
public final Key itemId;
|
||||
public final Vector3f scale;
|
||||
public final Vector3f position;
|
||||
public final Vector3f translation;
|
||||
public final float xRot;
|
||||
public final float yRot;
|
||||
public final Quaternionf rotation;
|
||||
public final ItemDisplayContext displayContext;
|
||||
public final Billboard billboard;
|
||||
public final float shadowRadius;
|
||||
public final float shadowStrength;
|
||||
public final boolean applyDyedColor;
|
||||
|
||||
public ItemDisplayFurnitureElementConfig(BiFunction<Player, ItemColorSource, Item<?>> item,
|
||||
public ItemDisplayFurnitureElementConfig(Key itemId,
|
||||
Vector3f scale,
|
||||
Vector3f position,
|
||||
Vector3f translation,
|
||||
@@ -65,10 +65,24 @@ public class ItemDisplayFurnitureElementConfig implements FurnitureElementConfig
|
||||
this.shadowRadius = shadowRadius;
|
||||
this.shadowStrength = shadowStrength;
|
||||
this.applyDyedColor = applyDyedColor;
|
||||
this.item = item;
|
||||
this.lazyMetadataPacket = (player, source) -> {
|
||||
this.itemId = itemId;
|
||||
BiFunction<Player, FurnitureColorSource, Item<?>> itemFunction = (player, colorSource) -> {
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().createWrappedItem(itemId, player);
|
||||
if (applyDyedColor && colorSource != null && wrappedItem != null) {
|
||||
Optional.ofNullable(colorSource.dyedColor()).ifPresent(wrappedItem::dyedColor);
|
||||
Optional.ofNullable(colorSource.fireworkColors()).ifPresent(colors -> wrappedItem.fireworkExplosion(new FireworkExplosion(
|
||||
FireworkExplosion.Shape.SMALL_BALL,
|
||||
new IntArrayList(colors),
|
||||
new IntArrayList(),
|
||||
false,
|
||||
false
|
||||
)));
|
||||
}
|
||||
return Optional.ofNullable(wrappedItem).orElseGet(() -> BukkitItemManager.instance().createWrappedItem(ItemKeys.BARRIER, null));
|
||||
};
|
||||
this.metadata = (player, source) -> {
|
||||
List<Object> dataValues = new ArrayList<>();
|
||||
ItemDisplayEntityData.DisplayedItem.addEntityData(item.apply(player, source).getLiteralObject(), dataValues);
|
||||
ItemDisplayEntityData.DisplayedItem.addEntityData(itemFunction.apply(player, source).getLiteralObject(), dataValues);
|
||||
ItemDisplayEntityData.Scale.addEntityData(this.scale, dataValues);
|
||||
ItemDisplayEntityData.RotationLeft.addEntityData(this.rotation, dataValues);
|
||||
ItemDisplayEntityData.BillboardConstraints.addEntityData(this.billboard.id(), dataValues);
|
||||
@@ -81,52 +95,56 @@ public class ItemDisplayFurnitureElementConfig implements FurnitureElementConfig
|
||||
}
|
||||
|
||||
public Vector3f scale() {
|
||||
return scale;
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
public Vector3f position() {
|
||||
return position;
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public Vector3f translation() {
|
||||
return translation;
|
||||
return this.translation;
|
||||
}
|
||||
|
||||
public float xRot() {
|
||||
return xRot;
|
||||
return this.xRot;
|
||||
}
|
||||
|
||||
public float yRot() {
|
||||
return yRot;
|
||||
return this.yRot;
|
||||
}
|
||||
|
||||
public Quaternionf rotation() {
|
||||
return rotation;
|
||||
return this.rotation;
|
||||
}
|
||||
|
||||
public ItemDisplayContext displayContext() {
|
||||
return displayContext;
|
||||
return this.displayContext;
|
||||
}
|
||||
|
||||
public Billboard billboard() {
|
||||
return billboard;
|
||||
return this.billboard;
|
||||
}
|
||||
|
||||
public float shadowRadius() {
|
||||
return shadowRadius;
|
||||
return this.shadowRadius;
|
||||
}
|
||||
|
||||
public float shadowStrength() {
|
||||
return shadowStrength;
|
||||
return this.shadowStrength;
|
||||
}
|
||||
|
||||
public boolean applyDyedColor() {
|
||||
return applyDyedColor;
|
||||
return this.applyDyedColor;
|
||||
}
|
||||
|
||||
public Key itemId() {
|
||||
return this.itemId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDisplayFurnitureElement create(@NotNull Furniture furniture) {
|
||||
return new ItemDisplayFurnitureElement(this);
|
||||
return new ItemDisplayFurnitureElement(furniture, this);
|
||||
}
|
||||
|
||||
public static class Factory implements FurnitureElementConfigFactory<ItemDisplayFurnitureElement> {
|
||||
@@ -136,22 +154,9 @@ public class ItemDisplayFurnitureElementConfig implements FurnitureElementConfig
|
||||
Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), "warning.config.furniture.element.item_display.missing_item"));
|
||||
boolean applyDyedColor = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("apply-dyed-color", true), "apply-dyed-color");
|
||||
return new ItemDisplayFurnitureElementConfig(
|
||||
(player, colorSource) -> {
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().createWrappedItem(itemId, player);
|
||||
if (applyDyedColor && colorSource != null && wrappedItem != null) {
|
||||
Optional.ofNullable(colorSource.dyedColor()).ifPresent(wrappedItem::dyedColor);
|
||||
Optional.ofNullable(colorSource.fireworkColors()).ifPresent(colors -> wrappedItem.fireworkExplosion(new FireworkExplosion(
|
||||
FireworkExplosion.Shape.SMALL_BALL,
|
||||
new IntArrayList(colors),
|
||||
new IntArrayList(),
|
||||
false,
|
||||
false
|
||||
)));
|
||||
}
|
||||
return Optional.ofNullable(wrappedItem).orElseGet(() -> BukkitItemManager.instance().createWrappedItem(ItemKeys.BARRIER, null));
|
||||
},
|
||||
itemId,
|
||||
ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("scale", 1f), "scale"),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position"),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0f), "position"),
|
||||
ResourceConfigUtils.getAsVector3f(arguments.get("translation"), "translation"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("pitch", 0f), "pitch"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("yaw", 0f), "yaw"),
|
||||
@@ -164,4 +169,23 @@ public class ItemDisplayFurnitureElementConfig implements FurnitureElementConfig
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ItemDisplayFurnitureElementConfig{" +
|
||||
"metadata=" + metadata +
|
||||
", itemId=" + itemId +
|
||||
", scale=" + scale +
|
||||
", position=" + position +
|
||||
", translation=" + translation +
|
||||
", xRot=" + xRot +
|
||||
", yRot=" + yRot +
|
||||
", rotation=" + rotation +
|
||||
", displayContext=" + displayContext +
|
||||
", billboard=" + billboard +
|
||||
", shadowRadius=" + shadowRadius +
|
||||
", shadowStrength=" + shadowStrength +
|
||||
", applyDyedColor=" + applyDyedColor +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ 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;
|
||||
@@ -54,4 +55,9 @@ public abstract class AbstractFurnitureHitBox implements FurnitureHitBox {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.data.BaseEntityData;
|
||||
import net.momirealms.craftengine.bukkit.entity.data.InteractionEntityData;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
@@ -14,15 +15,15 @@ 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[] entityIds;
|
||||
private final int interactionId;
|
||||
private final Object spawnPacket;
|
||||
private final Object despawnPacket;
|
||||
|
||||
public InteractionFurnitureHitbox(Furniture furniture, InteractionFurnitureHitboxConfig config) {
|
||||
super(furniture, config);
|
||||
@@ -31,20 +32,21 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
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());
|
||||
int interactionId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
this.entityIds = new int[] {interactionId};
|
||||
List<Object> values = new ArrayList<>(3);
|
||||
this.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);
|
||||
InteractionEntityData.Responsive.addEntityDataIfNotDefaultValue(config.responsive, values);
|
||||
if (config.invisible) {
|
||||
BaseEntityData.SharedFlags.addEntityDataIfNotDefaultValue((byte) 0x20, values);
|
||||
}
|
||||
this.spawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(List.of(
|
||||
FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
interactionId, UUID.randomUUID(), position.x, position.y, position.z, 0, position.yRot,
|
||||
this.interactionId, UUID.randomUUID(), position.x, position.y, position.z, 0, position.yRot,
|
||||
MEntityTypes.INTERACTION, 0, CoreReflections.instance$Vec3$Zero, 0
|
||||
),
|
||||
FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(interactionId, values)
|
||||
FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.interactionId, values)
|
||||
));
|
||||
this.despawnPacket = createDespawnPacket(this.entityIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,13 +55,8 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(Player player) {
|
||||
player.sendPacket(this.despawnPacket, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AABB aabb() {
|
||||
return this.aabb;
|
||||
public AABB[] aabb() {
|
||||
return new AABB[] { this.aabb };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,13 +65,18 @@ public class InteractionFurnitureHitbox extends AbstractFurnitureHitBox {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collider collider() {
|
||||
return this.collider;
|
||||
public List<Collider> colliders() {
|
||||
return List.of(this.collider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] virtualEntityIds() {
|
||||
return this.entityIds;
|
||||
return new int[] { this.interactionId };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectVirtualEntityIds(Consumer<Integer> collector) {
|
||||
collector.accept(this.interactionId);
|
||||
}
|
||||
|
||||
public InteractionFurnitureHitboxConfig config() {
|
||||
|
||||
@@ -5,27 +5,34 @@ import net.momirealms.craftengine.core.entity.furniture.hitbox.AbstractFurniture
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfigFactory;
|
||||
import net.momirealms.craftengine.core.entity.seat.SeatConfig;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class InteractionFurnitureHitboxConfig extends AbstractFurnitureHitBoxConfig<InteractionFurnitureHitbox> {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
public static final InteractionFurnitureHitboxConfig DEFAULT = new InteractionFurnitureHitboxConfig(new SeatConfig[0], new Vector3f(), false, false, false, new Vector3f(1,1,1), true);
|
||||
public static final InteractionFurnitureHitboxConfig DEFAULT = new InteractionFurnitureHitboxConfig(new SeatConfig[0], new Vector3f(), false, false, false, false, new Vector3f(1,1,1), true);
|
||||
|
||||
public final Vector3f size;
|
||||
public final boolean responsive;
|
||||
public final boolean invisible;
|
||||
|
||||
public InteractionFurnitureHitboxConfig(SeatConfig[] seats,
|
||||
Vector3f position,
|
||||
boolean canUseItemOn,
|
||||
boolean blocksBuilding,
|
||||
boolean canBeHitByProjectile,
|
||||
boolean invisible,
|
||||
Vector3f size,
|
||||
boolean responsive) {
|
||||
super(seats, position, canUseItemOn, blocksBuilding, canBeHitByProjectile);
|
||||
this.size = size;
|
||||
this.responsive = responsive;
|
||||
this.invisible = invisible;
|
||||
}
|
||||
|
||||
public Vector3f size() {
|
||||
@@ -36,6 +43,18 @@ public class InteractionFurnitureHitboxConfig extends AbstractFurnitureHitBoxCon
|
||||
return responsive;
|
||||
}
|
||||
|
||||
public boolean invisible() {
|
||||
return invisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForPlacement(WorldPosition targetPos, Consumer<AABB> aabbConsumer) {
|
||||
if (this.blocksBuilding) {
|
||||
Vec3d relativePosition = Furniture.getRelativePosition(targetPos, this.position);
|
||||
aabbConsumer.accept(AABB.fromInteraction(relativePosition, size.x, size.y));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionFurnitureHitbox create(Furniture furniture) {
|
||||
return new InteractionFurnitureHitbox(furniture, this);
|
||||
@@ -45,7 +64,7 @@ public class InteractionFurnitureHitboxConfig extends AbstractFurnitureHitBoxCon
|
||||
|
||||
@Override
|
||||
public InteractionFurnitureHitboxConfig create(Map<String, Object> arguments) {
|
||||
Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position");
|
||||
Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0), "position");
|
||||
float width;
|
||||
float height;
|
||||
if (arguments.containsKey("scale")) {
|
||||
@@ -60,9 +79,10 @@ public class InteractionFurnitureHitboxConfig extends AbstractFurnitureHitBoxCon
|
||||
boolean interactive = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("interactive", true), "interactive");
|
||||
boolean canBeHitByProjectile = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("can-be-hit-by-projectile", false), "can-be-hit-by-projectile");
|
||||
boolean blocksBuilding = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blocks-building", true), "blocks-building");
|
||||
boolean invisible = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("invisible", false), "invisible");
|
||||
return new InteractionFurnitureHitboxConfig(
|
||||
SeatConfig.fromObj(arguments.get("seats")),
|
||||
position, canUseOn, blocksBuilding, canBeHitByProjectile,
|
||||
position, canUseOn, blocksBuilding, canBeHitByProjectile, invisible,
|
||||
new Vector3f(width, height, width),
|
||||
interactive
|
||||
);
|
||||
|
||||
@@ -1,18 +1,46 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptPlaceEvent;
|
||||
import net.momirealms.craftengine.bukkit.api.event.FurniturePlaceEvent;
|
||||
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;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
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.pack.PendingConfigSection;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
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.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class FurnitureItemBehavior extends ItemBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
@@ -23,7 +51,7 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
}
|
||||
|
||||
public Key furnitureId() {
|
||||
return id;
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,121 +60,96 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
}
|
||||
|
||||
public InteractionResult place(UseOnContext context) {
|
||||
// Optional<FurnitureConfig> optionalCustomFurniture = BukkitFurnitureManager.instance().furnitureById(this.id);
|
||||
// if (optionalCustomFurniture.isEmpty()) {
|
||||
// CraftEngine.instance().logger().warn("Furniture " + this.id + " not found");
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
// FurnitureConfig customFurniture = optionalCustomFurniture.get();
|
||||
//
|
||||
// Direction clickedFace = context.getClickedFace();
|
||||
// AnchorType anchorType = switch (clickedFace) {
|
||||
// case EAST, WEST, NORTH, SOUTH -> AnchorType.WALL;
|
||||
// case UP -> AnchorType.GROUND;
|
||||
// case DOWN -> AnchorType.CEILING;
|
||||
// };
|
||||
//
|
||||
// FurnitureConfig.Variant placement = customFurniture.getPlacement(anchorType);
|
||||
// if (placement == null) {
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
//
|
||||
// Player player = context.getPlayer();
|
||||
// // todo adventure check
|
||||
// if (player != null && player.isAdventureMode()) {
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
//
|
||||
// Vec3d clickedPosition = context.getClickLocation();
|
||||
//
|
||||
// // trigger event
|
||||
// org.bukkit.entity.Player bukkitPlayer = player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null;
|
||||
// World world = (World) context.getLevel().platformWorld();
|
||||
//
|
||||
// // get position and rotation for placement
|
||||
// Vec3d finalPlacePosition;
|
||||
// double furnitureYaw;
|
||||
// if (anchorType == AnchorType.WALL) {
|
||||
// furnitureYaw = Direction.getYaw(clickedFace);
|
||||
// if (clickedFace == Direction.EAST || clickedFace == Direction.WEST) {
|
||||
// Pair<Double, Double> xz = placement.alignmentRule().apply(Pair.of(clickedPosition.y(), clickedPosition.z()));
|
||||
// finalPlacePosition = new Vec3d(clickedPosition.x(), xz.left(), xz.right());
|
||||
// } else {
|
||||
// Pair<Double, Double> xz = placement.alignmentRule().apply(Pair.of(clickedPosition.x(), clickedPosition.y()));
|
||||
// finalPlacePosition = new Vec3d(xz.left(), xz.right(), clickedPosition.z());
|
||||
// }
|
||||
// } else {
|
||||
// furnitureYaw = placement.rotationRule().apply(180 + (player != null ? player.yRot() : 0));
|
||||
// Pair<Double, Double> xz = placement.alignmentRule().apply(Pair.of(clickedPosition.x(), clickedPosition.z()));
|
||||
// finalPlacePosition = new Vec3d(xz.left(), clickedPosition.y(), xz.right());
|
||||
// }
|
||||
//
|
||||
// Location furnitureLocation = new Location(world, finalPlacePosition.x(), finalPlacePosition.y(), finalPlacePosition.z(), (float) furnitureYaw, 0);
|
||||
//
|
||||
// List<AABB> aabbs = new ArrayList<>();
|
||||
// for (HitBoxConfig hitBoxConfig : placement.hitBoxConfigs()) {
|
||||
// hitBoxConfig.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())) {
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!BukkitCraftEngine.instance().antiGriefProvider().canPlace(bukkitPlayer, furnitureLocation)) {
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
//
|
||||
// if (player != null) {
|
||||
// FurnitureAttemptPlaceEvent attemptPlaceEvent = new FurnitureAttemptPlaceEvent(bukkitPlayer, customFurniture, anchorType, furnitureLocation.clone(),
|
||||
// DirectionUtils.toBlockFace(clickedFace), context.getHand(), world.getBlockAt(context.getClickedPos().x(), context.getClickedPos().y(), context.getClickedPos().z()));
|
||||
// if (EventUtils.fireAndCheckCancel(attemptPlaceEvent)) {
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Item<?> item = context.getItem();
|
||||
// // 不可能
|
||||
// if (ItemUtils.isEmpty(item)) return InteractionResult.FAIL;
|
||||
//
|
||||
// BukkitFurniture bukkitFurniture = BukkitFurnitureManager.instance().place(
|
||||
// furnitureLocation.clone(), customFurniture,
|
||||
// FurnitureDataAccessor.builder()
|
||||
// .item(item.copyWithCount(1))
|
||||
// .anchorType(anchorType)
|
||||
// .dyedColor(item.dyedColor().orElse(null))
|
||||
// .fireworkExplosionColors(item.fireworkExplosion().map(explosion -> explosion.colors().toIntArray()).orElse(null))
|
||||
// .build(), false);
|
||||
//
|
||||
// if (player != null) {
|
||||
// FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, bukkitFurniture, furnitureLocation, context.getHand());
|
||||
// if (EventUtils.fireAndCheckCancel(placeEvent)) {
|
||||
// bukkitFurniture.destroy();
|
||||
// return InteractionResult.FAIL;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Cancellable dummy = Cancellable.dummy();
|
||||
// PlayerOptionalContext functionContext = PlayerOptionalContext.of(player, ContextHolder.builder()
|
||||
// .withParameter(DirectContextParameters.FURNITURE, bukkitFurniture)
|
||||
// .withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(furnitureLocation))
|
||||
// .withParameter(DirectContextParameters.EVENT, dummy)
|
||||
// .withParameter(DirectContextParameters.HAND, context.getHand())
|
||||
// .withParameter(DirectContextParameters.ITEM_IN_HAND, item)
|
||||
// );
|
||||
// customFurniture.execute(functionContext, EventTrigger.PLACE);
|
||||
// if (dummy.isCancelled()) {
|
||||
// return InteractionResult.SUCCESS_AND_CANCEL;
|
||||
// }
|
||||
//
|
||||
// if (player != null) {
|
||||
// if (!player.canInstabuild()) {
|
||||
// item.count(item.count() - 1);
|
||||
// }
|
||||
// player.swingHand(context.getHand());
|
||||
// }
|
||||
//
|
||||
// context.getLevel().playBlockSound(finalPlacePosition, customFurniture.settings().sounds().placeSound());
|
||||
Optional<FurnitureConfig> optionalCustomFurniture = BukkitFurnitureManager.instance().furnitureById(this.id);
|
||||
if (optionalCustomFurniture.isEmpty()) {
|
||||
CraftEngine.instance().logger().warn("Furniture " + this.id + " not found");
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
FurnitureConfig customFurniture = optionalCustomFurniture.get();
|
||||
FurnitureVariant variant = customFurniture.anyVariant();
|
||||
if (variant == null) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
Player player = context.getPlayer();
|
||||
if (player != null && player.isAdventureMode()) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
Vec3d clickedPosition = context.getClickLocation();
|
||||
|
||||
// trigger event
|
||||
org.bukkit.entity.Player bukkitPlayer = player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null;
|
||||
World world = (World) context.getLevel().platformWorld();
|
||||
|
||||
// get position and rotation for placement
|
||||
Vec3d finalPlacePosition = clickedPosition;
|
||||
double furnitureYaw = 180 + (player != null ? player.yRot() : 0);
|
||||
|
||||
Location furnitureLocation = new Location(world, finalPlacePosition.x(), finalPlacePosition.y(), finalPlacePosition.z(), (float) furnitureYaw, 0);
|
||||
WorldPosition furniturePos = LocationUtils.toWorldPosition(furnitureLocation);
|
||||
List<AABB> aabbs = new ArrayList<>();
|
||||
// 收集阻挡的碰撞箱
|
||||
for (FurnitureHitBoxConfig<?> hitBoxConfig : variant.hitBoxConfigs()) {
|
||||
hitBoxConfig.prepareForPlacement(furniturePos, 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())) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
// 检查其他插件兼容性
|
||||
if (!BukkitCraftEngine.instance().antiGriefProvider().canPlace(bukkitPlayer, furnitureLocation)) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
// 触发尝试放置的事件
|
||||
if (player != null) {
|
||||
FurnitureAttemptPlaceEvent attemptPlaceEvent = new FurnitureAttemptPlaceEvent(bukkitPlayer, customFurniture, variant, furnitureLocation.clone(), context.getHand(), world.getBlockAt(context.getClickedPos().x(), context.getClickedPos().y(), context.getClickedPos().z()));
|
||||
if (EventUtils.fireAndCheckCancel(attemptPlaceEvent)) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
Item<?> item = context.getItem();
|
||||
if (ItemUtils.isEmpty(item)) return InteractionResult.FAIL;
|
||||
// 获取家具物品的一些属性
|
||||
FurnitureDataAccessor dataAccessor = FurnitureDataAccessor.of(new CompoundTag());
|
||||
dataAccessor.setVariant(variant.name());
|
||||
dataAccessor.setItem(item.copyWithCount(1));
|
||||
dataAccessor.setDyedColor(item.dyedColor().orElse(null));
|
||||
dataAccessor.setFireworkExplosionColors(item.fireworkExplosion().map(explosion -> explosion.colors().toIntArray()).orElse(null));
|
||||
// 放置家具
|
||||
BukkitFurniture bukkitFurniture = BukkitFurnitureManager.instance().place(furnitureLocation.clone(), customFurniture, dataAccessor, false);
|
||||
// 触发放置事件
|
||||
if (player != null) {
|
||||
FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, bukkitFurniture, furnitureLocation, context.getHand());
|
||||
if (EventUtils.fireAndCheckCancel(placeEvent)) {
|
||||
bukkitFurniture.destroy();
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
// 触发ce事件
|
||||
Cancellable dummy = Cancellable.dummy();
|
||||
PlayerOptionalContext functionContext = PlayerOptionalContext.of(player, ContextHolder.builder()
|
||||
.withParameter(DirectContextParameters.FURNITURE, bukkitFurniture)
|
||||
.withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(furnitureLocation))
|
||||
.withParameter(DirectContextParameters.EVENT, dummy)
|
||||
.withParameter(DirectContextParameters.HAND, context.getHand())
|
||||
.withParameter(DirectContextParameters.ITEM_IN_HAND, item)
|
||||
);
|
||||
customFurniture.execute(functionContext, EventTrigger.PLACE);
|
||||
if (dummy.isCancelled()) {
|
||||
return InteractionResult.SUCCESS_AND_CANCEL;
|
||||
}
|
||||
// 后续处理
|
||||
if (player != null) {
|
||||
if (!player.canInstabuild()) {
|
||||
item.count(item.count() - 1);
|
||||
}
|
||||
player.swingHand(context.getHand());
|
||||
}
|
||||
context.getLevel().playBlockSound(finalPlacePosition, customFurniture.settings().sounds().placeSound());
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1247,7 +1247,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
CraftEngine.instance().logger().warn("Failed to get entityId from ServerboundPickItemFromEntityPacket", e);
|
||||
return;
|
||||
}
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByVirtualEntityId(entityId);
|
||||
if (furniture == null) return;
|
||||
Player player = (Player) user.platformPlayer();
|
||||
if (player == null) return;
|
||||
@@ -1469,6 +1469,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
player.setClientSideWorld(BukkitAdaptors.adapt(world));
|
||||
player.clearTrackedChunks();
|
||||
player.clearTrackedBlockEntities();
|
||||
player.clearTrackedFurniture();
|
||||
} else {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundRespawnPacket: World " + location + " does not exist");
|
||||
}
|
||||
@@ -1745,9 +1746,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
@Override
|
||||
public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
int entityId = ProtectedFieldVisitor.get().field$ClientboundMoveEntityPacket$entityId(packet);
|
||||
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
EntityPacketHandler handler = user.entityPacketHandlers().get(entityId);
|
||||
if (handler != null) {
|
||||
handler.handleMoveAndRotate(user, event, packet);
|
||||
@@ -1778,7 +1776,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
CraftEngine.instance().logger().warn("Failed to get entity id from ClientboundRotateHeadPacket", t);
|
||||
return;
|
||||
}
|
||||
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
|
||||
if (BukkitFurnitureManager.instance().isFurnitureMetaEntity(entityId)) {
|
||||
System.out.println("RotateHeadListener");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -1796,7 +1795,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
CraftEngine.instance().logger().warn("Failed to get entity id from ClientboundSetEntityMotionPacket", t);
|
||||
return;
|
||||
}
|
||||
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
|
||||
if (BukkitFurnitureManager.instance().isFurnitureMetaEntity(entityId)) {
|
||||
System.out.println("SetEntityMotionListener");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -3349,7 +3349,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
for (int i = 0, size = intList.size(); i < size; i++) {
|
||||
int entityId = intList.getInt(i);
|
||||
EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId);
|
||||
if (handler != null && handler.handleEntitiesRemove(intList)) {
|
||||
if (handler != null && handler.handleEntitiesRemove(user, intList)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -3698,7 +3698,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
public void onPacketReceive(NetWorkUser user, ByteBufPacketEvent event) {
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
int entityId = hasModelEngine() ? plugin.compatibilityManager().interactionToBaseEntity(buf.readVarInt()) : buf.readVarInt();
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByVirtualEntityId(entityId);
|
||||
if (furniture == null) return;
|
||||
int actionType = buf.readVarInt();
|
||||
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user;
|
||||
@@ -3799,7 +3799,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.aabb().clip(LocationUtils.toVec3d(eyeLocation), LocationUtils.toVec3d(endLocation));
|
||||
Optional<EntityHitResult> result = hitBox.clip(LocationUtils.toVec3d(eyeLocation), LocationUtils.toVec3d(endLocation));
|
||||
if (result.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -3976,16 +3976,19 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
this.handlers[MEntityTypes.ITEM_DISPLAY$registryId] = (user, event) -> {
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
int id = buf.readVarInt();
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
|
||||
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user;
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByMetaEntityId(id);
|
||||
if (furniture != null) {
|
||||
furniture.show((BukkitServerPlayer) user);
|
||||
event.setCancelled(true);
|
||||
serverPlayer.entityPacketHandlers().put(id, new FurniturePacketHandler(id, furniture.virtualEntityIds()));
|
||||
if (Config.enableEntityCulling()) {
|
||||
serverPlayer.addTrackedFurniture(id, furniture);
|
||||
} else {
|
||||
furniture.show(serverPlayer);
|
||||
}
|
||||
// fixme 外部模型
|
||||
// user.entityPacketHandlers().put(id, new FurniturePacketHandler(furniture.fakeEntityIds()));
|
||||
// user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false);
|
||||
// if (Config.hideBaseEntity() && !furniture.hasExternalModel()) {
|
||||
// event.setCancelled(true);
|
||||
// }
|
||||
if (Config.hideBaseEntity() && true) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else {
|
||||
user.entityPacketHandlers().put(id, ItemDisplayPacketHandler.INSTANCE);
|
||||
}
|
||||
@@ -3995,7 +3998,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
int id = buf.readVarInt();
|
||||
// Cancel collider entity packet
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByColliderEntityId(id);
|
||||
if (furniture != null) {
|
||||
event.setCancelled(true);
|
||||
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
|
||||
@@ -4006,7 +4009,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
int id = buf.readVarInt();
|
||||
// Cancel collider entity packet
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByColliderEntityId(id);
|
||||
if (furniture != null) {
|
||||
event.setCancelled(true);
|
||||
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.network.handler;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||
import net.momirealms.craftengine.core.plugin.network.NMSPacketEvent;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FurniturePacketHandler implements EntityPacketHandler {
|
||||
private final List<Integer> fakeEntities;
|
||||
private final int metaEntityId;
|
||||
private final int[] virtualHitboxEntities;
|
||||
|
||||
public FurniturePacketHandler(List<Integer> fakeEntities) {
|
||||
this.fakeEntities = fakeEntities;
|
||||
public FurniturePacketHandler(int metaEntityId, int[] virtualHitboxEntities) {
|
||||
this.virtualHitboxEntities = virtualHitboxEntities;
|
||||
this.metaEntityId = metaEntityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleEntitiesRemove(IntList entityIds) {
|
||||
entityIds.addAll(this.fakeEntities);
|
||||
public boolean handleEntitiesRemove(NetWorkUser user, IntList entityIds) {
|
||||
((Player) user).removeTrackedFurniture(this.metaEntityId);
|
||||
for (int entityId : this.virtualHitboxEntities) {
|
||||
entityIds.add(entityId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,4 +33,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.entity.BlockEntity;
|
||||
import net.momirealms.craftengine.core.block.entity.render.ConstantBlockEntityRenderer;
|
||||
import net.momirealms.craftengine.core.entity.data.EntityData;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.player.GameMode;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
@@ -144,6 +145,7 @@ public class BukkitServerPlayer extends Player {
|
||||
private int lastStopMiningTick;
|
||||
// 跟踪到的方块实体渲染器
|
||||
private final Map<BlockPos, VirtualCullableObject> trackedBlockEntityRenderers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, VirtualCullableObject> trackedFurniture = new ConcurrentHashMap<>();
|
||||
private final EntityCulling culling;
|
||||
private Vec3d firstPersonCameraVec3;
|
||||
private Vec3d thirdPersonCameraVec3;
|
||||
@@ -603,44 +605,54 @@ public class BukkitServerPlayer extends Player {
|
||||
boolean useRayTracing = Config.entityCullingRayTracing();
|
||||
if (this.enableEntityCulling) {
|
||||
for (VirtualCullableObject cullableObject : this.trackedBlockEntityRenderers.values()) {
|
||||
CullingData cullingData = cullableObject.cullable.cullingData();
|
||||
if (cullingData != null) {
|
||||
boolean firstPersonVisible = this.culling.isVisible(cullingData, this.firstPersonCameraVec3, useRayTracing);
|
||||
// 之前可见
|
||||
if (cullableObject.isShown) {
|
||||
boolean thirdPersonVisible = this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing);
|
||||
if (!firstPersonVisible && !thirdPersonVisible) {
|
||||
cullableObject.setShown(this, false);
|
||||
}
|
||||
}
|
||||
// 之前不可见
|
||||
else {
|
||||
// 但是第一人称可见了
|
||||
if (firstPersonVisible) {
|
||||
// 下次再说
|
||||
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
|
||||
continue;
|
||||
}
|
||||
cullableObject.setShown(this, true);
|
||||
continue;
|
||||
}
|
||||
if (this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing)) {
|
||||
// 下次再说
|
||||
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
|
||||
continue;
|
||||
}
|
||||
cullableObject.setShown(this, true);
|
||||
}
|
||||
// 仍然不可见
|
||||
}
|
||||
} else {
|
||||
cullableObject.setShown(this, true);
|
||||
}
|
||||
cullEntity(useRayTracing, cullableObject);
|
||||
}
|
||||
for (VirtualCullableObject cullableObject : this.trackedFurniture.values()) {
|
||||
cullEntity(useRayTracing, cullableObject);
|
||||
}
|
||||
} else {
|
||||
for (VirtualCullableObject cullableObject : this.trackedBlockEntityRenderers.values()) {
|
||||
cullableObject.setShown(this, true);
|
||||
}
|
||||
for (VirtualCullableObject cullableObject : this.trackedFurniture.values()) {
|
||||
cullableObject.setShown(this, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cullEntity(boolean useRayTracing, VirtualCullableObject cullableObject) {
|
||||
CullingData cullingData = cullableObject.cullable.cullingData();
|
||||
if (cullingData != null) {
|
||||
boolean firstPersonVisible = this.culling.isVisible(cullingData, this.firstPersonCameraVec3, useRayTracing);
|
||||
// 之前可见
|
||||
if (cullableObject.isShown) {
|
||||
boolean thirdPersonVisible = this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing);
|
||||
if (!firstPersonVisible && !thirdPersonVisible) {
|
||||
cullableObject.setShown(this, false);
|
||||
}
|
||||
}
|
||||
// 之前不可见
|
||||
else {
|
||||
// 但是第一人称可见了
|
||||
if (firstPersonVisible) {
|
||||
// 下次再说
|
||||
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
|
||||
return;
|
||||
}
|
||||
cullableObject.setShown(this, true);
|
||||
return;
|
||||
}
|
||||
if (this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing)) {
|
||||
// 下次再说
|
||||
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
|
||||
return;
|
||||
}
|
||||
cullableObject.setShown(this, true);
|
||||
}
|
||||
// 仍然不可见
|
||||
}
|
||||
} else {
|
||||
cullableObject.setShown(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1427,6 +1439,24 @@ public class BukkitServerPlayer extends Player {
|
||||
this.trackedBlockEntityRenderers.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTrackedFurniture(int entityId, Furniture furniture) {
|
||||
this.trackedFurniture.put(entityId, new VirtualCullableObject(furniture));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTrackedFurniture(int entityId) {
|
||||
VirtualCullableObject remove = this.trackedFurniture.remove(entityId);
|
||||
if (remove != null && remove.isShown()) {
|
||||
remove.cullable().hide(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTrackedFurniture() {
|
||||
this.trackedFurniture.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldPosition eyePosition() {
|
||||
return LocationUtils.toWorldPosition(this.getEyeLocation());
|
||||
|
||||
@@ -124,7 +124,7 @@ public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
String variantName = e0.getKey();
|
||||
Map<String, Object> variantArguments = ResourceConfigUtils.getAsMap(e0.getValue(), variantName);
|
||||
Optional<Vector3f> optionalLootSpawnOffset = Optional.ofNullable(variantArguments.get("loot-spawn-offset")).map(it -> ResourceConfigUtils.getAsVector3f(it, "loot-spawn-offset"));
|
||||
List<FurnitureElementConfig<?>> elements = ResourceConfigUtils.parseConfigAsList(variantArguments.get("elementConfigs"), FurnitureElementConfigs::fromMap);
|
||||
List<FurnitureElementConfig<?>> elements = ResourceConfigUtils.parseConfigAsList(variantArguments.get("elements"), FurnitureElementConfigs::fromMap);
|
||||
|
||||
// fixme 外部模型不应该在这
|
||||
Optional<ExternalModel> externalModel;
|
||||
@@ -141,7 +141,12 @@ public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
hitboxes = List.of(defaultHitBox());
|
||||
}
|
||||
|
||||
// fixme 动态计算aabb,因为家具具有朝向
|
||||
AABB maxAABB = new AABB(0,0,0,1,1,1);
|
||||
|
||||
variants.put(variantName, new FurnitureVariant(
|
||||
variantName,
|
||||
parseCullingData(section.get("entity-culling"), maxAABB),
|
||||
elements.toArray(new FurnitureElementConfig[0]),
|
||||
hitboxes.toArray(new FurnitureHitBoxConfig[0]),
|
||||
externalModel,
|
||||
@@ -149,15 +154,13 @@ public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
));
|
||||
}
|
||||
|
||||
AABB maxAABB = null;
|
||||
|
||||
FurnitureConfig furniture = FurnitureConfig.builder()
|
||||
.id(id)
|
||||
.settings(FurnitureSettings.fromMap(MiscUtils.castToMap(section.get("settings"), true)))
|
||||
.variants(variants)
|
||||
.events(EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event")))
|
||||
.lootTable(LootTable.fromMap(MiscUtils.castToMap(section.get("loot"), true)))
|
||||
.cullingData(parseCullingData(section.get("entity-culling"), maxAABB))
|
||||
|
||||
.build();
|
||||
AbstractFurnitureManager.this.byId.put(id, furniture);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.momirealms.craftengine.core.entity.Entity;
|
||||
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElement;
|
||||
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElementConfig;
|
||||
@@ -15,13 +19,12 @@ import net.momirealms.craftengine.core.world.Cullable;
|
||||
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.jetbrains.annotations.Nullable;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class Furniture implements Cullable {
|
||||
@@ -29,18 +32,20 @@ public abstract class Furniture implements Cullable {
|
||||
public final FurnitureDataAccessor dataAccessor;
|
||||
public final WeakReference<Entity> metaDataEntity;
|
||||
|
||||
protected CullingData cullingData;
|
||||
protected FurnitureVariant currentVariant;
|
||||
protected FurnitureElement[] elements;
|
||||
protected Collider[] colliders;
|
||||
protected FurnitureHitBox[] hitboxes;
|
||||
|
||||
protected Int2ObjectMap<FurnitureHitBox> hitboxMap;
|
||||
protected int[] entityIds;
|
||||
protected int[] virtualEntityIds;
|
||||
protected int[] colliderEntityIds;
|
||||
|
||||
protected Furniture(Entity metaDataEntity, FurnitureDataAccessor data, FurnitureConfig config) {
|
||||
this.config = config;
|
||||
this.dataAccessor = data;
|
||||
this.metaDataEntity = new WeakReference<>(metaDataEntity);
|
||||
this.setVariant(config.getVariant(data));
|
||||
}
|
||||
|
||||
public WeakReference<Entity> metaDataEntity() {
|
||||
@@ -48,25 +53,24 @@ public abstract class Furniture implements Cullable {
|
||||
}
|
||||
|
||||
public FurnitureVariant getCurrentVariant() {
|
||||
return currentVariant;
|
||||
}
|
||||
|
||||
public String getCurrentVariantName() {
|
||||
return null;
|
||||
return this.currentVariant;
|
||||
}
|
||||
|
||||
public void setVariant(FurnitureVariant variant) {
|
||||
this.currentVariant = variant;
|
||||
WorldPosition position = this.position();
|
||||
this.hitboxMap = new Int2ObjectOpenHashMap<>();
|
||||
// 初始化家具元素
|
||||
IntList virtualEntityIds = new IntArrayList();
|
||||
FurnitureElementConfig<?>[] elementConfigs = variant.elementConfigs();
|
||||
this.elements = new FurnitureElement[elementConfigs.length];
|
||||
for (int i = 0; i < elementConfigs.length; i++) {
|
||||
this.elements[i] = elementConfigs[i].create(this);
|
||||
FurnitureElement element = elementConfigs[i].create(this);
|
||||
this.elements[i] = element;
|
||||
element.collectVirtualEntityId(virtualEntityIds::addLast);
|
||||
}
|
||||
// 初始化碰撞箱
|
||||
FurnitureHitBoxConfig<?>[] furnitureHitBoxConfigs = variant.furnitureHitBoxConfigs();
|
||||
List<Collider> colliders = new ArrayList<>(furnitureHitBoxConfigs.length);
|
||||
FurnitureHitBoxConfig<?>[] furnitureHitBoxConfigs = variant.hitBoxConfigs();
|
||||
ObjectArrayList<Collider> colliders = new ObjectArrayList<>(furnitureHitBoxConfigs.length);
|
||||
this.hitboxes = new FurnitureHitBox[furnitureHitBoxConfigs.length];
|
||||
for (int i = 0; i < furnitureHitBoxConfigs.length; i++) {
|
||||
FurnitureHitBox hitbox = furnitureHitBoxConfigs[i].create(this);
|
||||
@@ -74,12 +78,23 @@ public abstract class Furniture implements Cullable {
|
||||
for (int hitboxEntityId : hitbox.virtualEntityIds()) {
|
||||
this.hitboxMap.put(hitboxEntityId, hitbox);
|
||||
}
|
||||
Collider collider = hitbox.collider();
|
||||
if (collider != null) {
|
||||
colliders.add(collider);
|
||||
}
|
||||
colliders.addAll(hitbox.colliders());
|
||||
hitbox.collectVirtualEntityIds(virtualEntityIds::addLast);
|
||||
}
|
||||
// 虚拟碰撞箱的实体id
|
||||
this.virtualEntityIds = virtualEntityIds.toIntArray();
|
||||
this.colliders = colliders.toArray(new Collider[0]);
|
||||
this.colliderEntityIds = colliders.stream().mapToInt(Collider::entityId).toArray();
|
||||
this.cullingData = createCullingData(variant.cullingData());
|
||||
}
|
||||
|
||||
private CullingData createCullingData(CullingData parent) {
|
||||
if (parent == null) return null;
|
||||
AABB aabb = parent.aabb;
|
||||
WorldPosition position = position();
|
||||
Vec3d pos1 = getRelativePosition(position, new Vector3f((float) aabb.minX, (float) aabb.minY, (float) aabb.minZ));
|
||||
Vec3d pos2 = getRelativePosition(position, new Vector3f((float) aabb.maxX, (float) aabb.maxY, (float) aabb.maxZ));
|
||||
return new CullingData(new AABB(pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z), parent.maxDistance, parent.aabbExpansion, parent.rayTracing);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -90,15 +105,20 @@ public abstract class Furniture implements Cullable {
|
||||
@Nullable
|
||||
@Override
|
||||
public CullingData cullingData() {
|
||||
return this.config.cullingData();
|
||||
return this.cullingData;
|
||||
}
|
||||
|
||||
public Key id() {
|
||||
return this.config.id();
|
||||
}
|
||||
|
||||
public int[] entityIds() {
|
||||
return this.entityIds;
|
||||
// 会发给玩家的包
|
||||
public int[] virtualEntityIds() {
|
||||
return this.virtualEntityIds;
|
||||
}
|
||||
|
||||
public int[] colliderEntityIds() {
|
||||
return colliderEntityIds;
|
||||
}
|
||||
|
||||
public UUID uuid() {
|
||||
@@ -146,11 +166,11 @@ public abstract class Furniture implements Cullable {
|
||||
public abstract void destroy();
|
||||
|
||||
public FurnitureConfig config() {
|
||||
return config;
|
||||
return this.config;
|
||||
}
|
||||
|
||||
public FurnitureDataAccessor dataAccessor() {
|
||||
return dataAccessor;
|
||||
return this.dataAccessor;
|
||||
}
|
||||
|
||||
public Collider[] colliders() {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
|
||||
public record FurnitureColorSource(Color dyedColor, int[] fireworkColors) {
|
||||
}
|
||||
@@ -67,8 +67,6 @@ public interface FurnitureConfig {
|
||||
|
||||
}
|
||||
|
||||
CullingData cullingData();
|
||||
|
||||
static Builder builder() {
|
||||
return new FurnitureConfigImpl.BuilderImpl();
|
||||
}
|
||||
@@ -87,8 +85,6 @@ public interface FurnitureConfig {
|
||||
|
||||
Builder behavior(FurnitureBehavior behavior);
|
||||
|
||||
Builder cullingData(CullingData cullingData);
|
||||
|
||||
FurnitureConfig build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ class FurnitureConfigImpl implements FurnitureConfig {
|
||||
private final Map<String, FurnitureVariant> variants;
|
||||
private final Map<EventTrigger, List<Function<Context>>> events;
|
||||
private final FurnitureBehavior behavior;
|
||||
private final CullingData cullingData;
|
||||
@Nullable
|
||||
private final LootTable<?> lootTable;
|
||||
|
||||
@@ -32,14 +31,12 @@ class FurnitureConfigImpl implements FurnitureConfig {
|
||||
@NotNull Map<String, FurnitureVariant> variants,
|
||||
@NotNull Map<EventTrigger, List<Function<Context>>> events,
|
||||
@NotNull FurnitureBehavior behavior,
|
||||
@Nullable CullingData cullingData,
|
||||
@Nullable LootTable<?> lootTable) {
|
||||
this.id = id;
|
||||
this.settings = settings;
|
||||
this.variants = ImmutableMap.copyOf(variants);
|
||||
this.lootTable = lootTable;
|
||||
this.behavior = behavior;
|
||||
this.cullingData = cullingData;
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
@@ -75,11 +72,6 @@ class FurnitureConfigImpl implements FurnitureConfig {
|
||||
return this.behavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CullingData cullingData() {
|
||||
return this.cullingData;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FurnitureVariant getVariant(String variantName) {
|
||||
@@ -93,11 +85,10 @@ class FurnitureConfigImpl implements FurnitureConfig {
|
||||
private Map<EventTrigger, List<Function<Context>>> events;
|
||||
private LootTable<?> lootTable;
|
||||
private FurnitureBehavior behavior = EmptyFurnitureBehavior.INSTANCE;
|
||||
private CullingData cullingData;
|
||||
|
||||
@Override
|
||||
public FurnitureConfig build() {
|
||||
return new FurnitureConfigImpl(this.id, this.settings, this.variants, this.events, this.behavior, this.cullingData, this.lootTable);
|
||||
return new FurnitureConfigImpl(this.id, this.settings, this.variants, this.events, this.behavior, this.lootTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,12 +121,6 @@ class FurnitureConfigImpl implements FurnitureConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder cullingData(CullingData cullingData) {
|
||||
this.cullingData = cullingData;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder behavior(FurnitureBehavior behavior) {
|
||||
this.behavior = behavior;
|
||||
|
||||
@@ -68,12 +68,20 @@ public class FurnitureDataAccessor {
|
||||
this.data.putByteArray(ITEM, item.toByteArray());
|
||||
}
|
||||
|
||||
public FurnitureColorSource getColorSource() {
|
||||
return new FurnitureColorSource(dyedColor().orElse(null), fireworkExplosionColors().orElse(null));
|
||||
}
|
||||
|
||||
public Optional<int[]> fireworkExplosionColors() {
|
||||
if (this.data.containsKey(FIREWORK_EXPLOSION_COLORS)) return Optional.of(this.data.getIntArray(FIREWORK_EXPLOSION_COLORS));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void setFireworkExplosionColors(int[] colors) {
|
||||
if (colors == null) {
|
||||
this.data.remove(FIREWORK_EXPLOSION_COLORS);
|
||||
return;
|
||||
}
|
||||
this.data.putIntArray(FIREWORK_EXPLOSION_COLORS, colors);
|
||||
}
|
||||
|
||||
@@ -82,7 +90,11 @@ public class FurnitureDataAccessor {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void setDyedColor(Color color) {
|
||||
public void setDyedColor(@Nullable Color color) {
|
||||
if (color == null) {
|
||||
this.data.remove(DYED_COLOR);
|
||||
return;
|
||||
}
|
||||
this.data.putInt(DYED_COLOR, color.color());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.AbstractEntity;
|
||||
import net.momirealms.craftengine.core.plugin.Manageable;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
@@ -31,16 +30,14 @@ public interface FurnitureManager extends Manageable {
|
||||
|
||||
Map<Key, FurnitureConfig> loadedFurniture();
|
||||
|
||||
boolean isFurnitureRealEntity(int entityId);
|
||||
boolean isFurnitureMetaEntity(int entityId);
|
||||
|
||||
@Nullable
|
||||
Furniture loadedFurnitureByRealEntityId(int entityId);
|
||||
Furniture loadedFurnitureByMetaEntityId(int entityId);
|
||||
|
||||
@Nullable
|
||||
default Furniture loadedFurnitureByRealEntity(AbstractEntity entity) {
|
||||
return loadedFurnitureByRealEntityId(entity.entityID());
|
||||
}
|
||||
Furniture loadedFurnitureByVirtualEntityId(int entityId);
|
||||
|
||||
@Nullable
|
||||
Furniture loadedFurnitureByEntityId(int entityId);
|
||||
Furniture loadedFurnitureByColliderEntityId(int entityId);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,16 @@ package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.furniture.element.FurnitureElementConfig;
|
||||
import net.momirealms.craftengine.core.entity.furniture.hitbox.FurnitureHitBoxConfig;
|
||||
import net.momirealms.craftengine.core.plugin.entityculling.CullingData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record FurnitureVariant(FurnitureElementConfig<?>[] elementConfigs,
|
||||
FurnitureHitBoxConfig<?>[] furnitureHitBoxConfigs,
|
||||
public record FurnitureVariant(String name,
|
||||
@Nullable CullingData cullingData,
|
||||
FurnitureElementConfig<?>[] elementConfigs,
|
||||
FurnitureHitBoxConfig<?>[] hitBoxConfigs,
|
||||
Optional<ExternalModel> externalModel,
|
||||
Optional<Vector3f> dropOffset) {
|
||||
}
|
||||
@@ -2,8 +2,14 @@ package net.momirealms.craftengine.core.entity.furniture.element;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface FurnitureElement {
|
||||
|
||||
int[] virtualEntityIds();
|
||||
|
||||
void collectVirtualEntityId(Consumer<Integer> collector);
|
||||
|
||||
void show(Player player);
|
||||
|
||||
void hide(Player player);
|
||||
|
||||
@@ -10,7 +10,11 @@ public abstract class AbstractFurnitureHitBoxConfig<H extends FurnitureHitBox> i
|
||||
protected final boolean blocksBuilding;
|
||||
protected final boolean canBeHitByProjectile;
|
||||
|
||||
public AbstractFurnitureHitBoxConfig(SeatConfig[] seats, Vector3f position, boolean canUseItemOn, boolean blocksBuilding, boolean canBeHitByProjectile) {
|
||||
public AbstractFurnitureHitBoxConfig(SeatConfig[] seats,
|
||||
Vector3f position,
|
||||
boolean canUseItemOn,
|
||||
boolean blocksBuilding,
|
||||
boolean canBeHitByProjectile) {
|
||||
this.seats = seats;
|
||||
this.position = position;
|
||||
this.canUseItemOn = canUseItemOn;
|
||||
|
||||
@@ -4,26 +4,41 @@ import net.momirealms.craftengine.core.entity.furniture.Collider;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface FurnitureHitBox extends SeatOwner {
|
||||
|
||||
Seat<FurnitureHitBox>[] seats();
|
||||
|
||||
AABB aabb();
|
||||
|
||||
Vec3d position();
|
||||
|
||||
@Nullable
|
||||
Collider collider();
|
||||
Seat<FurnitureHitBox>[] seats();
|
||||
|
||||
AABB[] aabb();
|
||||
|
||||
List<Collider> colliders();
|
||||
|
||||
int[] virtualEntityIds();
|
||||
|
||||
void collectVirtualEntityIds(Consumer<Integer> collector);
|
||||
|
||||
void show(Player player);
|
||||
|
||||
void hide(Player player);
|
||||
|
||||
FurnitureHitBoxConfig<?> config();
|
||||
|
||||
default Optional<EntityHitResult> clip(Vec3d min, Vec3d max) {
|
||||
for (AABB value : aabb()) {
|
||||
Optional<EntityHitResult> clip = value.clip(min, max);
|
||||
if (clip.isPresent()) {
|
||||
return clip;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@ package net.momirealms.craftengine.core.entity.furniture.hitbox;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.seat.SeatConfig;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface FurnitureHitBoxConfig<H extends FurnitureHitBox> {
|
||||
|
||||
H create(Furniture furniture);
|
||||
@@ -17,4 +21,6 @@ public interface FurnitureHitBoxConfig<H extends FurnitureHitBox> {
|
||||
boolean canBeHitByProjectile();
|
||||
|
||||
boolean canUseItemOn();
|
||||
|
||||
void prepareForPlacement(WorldPosition targetPos, Consumer<AABB> aabbConsumer);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.advancement.AdvancementType;
|
||||
import net.momirealms.craftengine.core.block.entity.render.ConstantBlockEntityRenderer;
|
||||
import net.momirealms.craftengine.core.entity.AbstractEntity;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.context.CooldownData;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
@@ -217,12 +218,18 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
|
||||
public abstract void removeTrackedBlockEntities(Collection<BlockPos> renders);
|
||||
|
||||
public abstract void addTrackedFurniture(int entityId, Furniture furniture);
|
||||
|
||||
public abstract void clearTrackedBlockEntities();
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
}
|
||||
|
||||
public abstract void removeTrackedFurniture(int entityId);
|
||||
|
||||
public abstract void clearTrackedFurniture();
|
||||
|
||||
public abstract WorldPosition eyePosition();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@ public class FurnitureParameterProvider implements ChainParameterProvider<Furnit
|
||||
static {
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.ID, f -> f.config().id());
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.UUID, Furniture::uuid);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.VARIANT, Furniture::getCurrentVariantName);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.VARIANT, f -> f.getCurrentVariant().name());
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.X, furniture -> furniture.position().x());
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.Y, furniture -> furniture.position().y());
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.Z, furniture -> furniture.position().z());
|
||||
|
||||
@@ -5,7 +5,7 @@ import net.momirealms.craftengine.core.entity.player.Player;
|
||||
|
||||
public interface EntityPacketHandler {
|
||||
|
||||
default boolean handleEntitiesRemove(IntList entityIds) {
|
||||
default boolean handleEntitiesRemove(NetWorkUser user, IntList entityIds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +266,8 @@ public final class ResourceConfigUtils {
|
||||
if (o == null) return new Vector3f();
|
||||
if (o instanceof List<?> list && list.size() == 3) {
|
||||
return new Vector3f(Float.parseFloat(list.get(0).toString()), Float.parseFloat(list.get(1).toString()), Float.parseFloat(list.get(2).toString()));
|
||||
} else if (o instanceof Number number) {
|
||||
return new Vector3f(number.floatValue());
|
||||
} else {
|
||||
String stringFormat = o.toString();
|
||||
String[] split = stringFormat.split(",");
|
||||
|
||||
Reference in New Issue
Block a user