mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
重构家具读取
This commit is contained in:
@@ -6,7 +6,8 @@ import ch.njol.skript.lang.Expression;
|
||||
import ch.njol.skript.lang.SkriptParser;
|
||||
import ch.njol.util.Kleenean;
|
||||
import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -23,9 +24,9 @@ public class EffRemoveFurniture extends Effect {
|
||||
protected void execute(Event e) {
|
||||
for (Entity entity : entities.getArray(e)) {
|
||||
if (CraftEngineFurniture.isFurniture(entity)) {
|
||||
LoadedFurniture loadedFurniture = CraftEngineFurniture.getLoadedFurnitureByBaseEntity(entity);
|
||||
if (loadedFurniture != null) {
|
||||
loadedFurniture.destroy();
|
||||
Furniture bukkitFurniture = CraftEngineFurniture.getLoadedFurnitureByBaseEntity(entity);
|
||||
if (bukkitFurniture != null) {
|
||||
bukkitFurniture.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@ package net.momirealms.craftengine.bukkit.api;
|
||||
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
|
||||
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -29,4 +32,8 @@ public final class BukkitAdaptors {
|
||||
public static BukkitBlockInWorld adapt(final Block block) {
|
||||
return new BukkitBlockInWorld(block);
|
||||
}
|
||||
|
||||
public static Location toLocation(WorldPosition position) {
|
||||
return LocationUtils.toLocation(position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package net.momirealms.craftengine.bukkit.api;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
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.world.BukkitWorld;
|
||||
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
|
||||
import net.momirealms.craftengine.core.entity.furniture.CustomFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureExtraData;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
@@ -48,7 +49,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@Nullable
|
||||
public static LoadedFurniture place(Location location, Key furnitureId) {
|
||||
public static Furniture place(Location location, Key furnitureId) {
|
||||
CustomFurniture furniture = byId(furnitureId);
|
||||
if (furniture == null) return null;
|
||||
return place(location, furnitureId, furniture.getAnyPlacement());
|
||||
@@ -63,7 +64,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@Nullable
|
||||
public static LoadedFurniture place(Location location, Key furnitureId, AnchorType anchorType) {
|
||||
public static Furniture place(Location location, Key furnitureId, AnchorType anchorType) {
|
||||
CustomFurniture furniture = byId(furnitureId);
|
||||
if (furniture == null) return null;
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), true);
|
||||
@@ -78,7 +79,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@NotNull
|
||||
public static LoadedFurniture place(Location location, CustomFurniture furniture, AnchorType anchorType) {
|
||||
public static Furniture place(Location location, CustomFurniture furniture, AnchorType anchorType) {
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), true);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@Nullable
|
||||
public static LoadedFurniture place(Location location, Key furnitureId, AnchorType anchorType, boolean playSound) {
|
||||
public static Furniture place(Location location, Key furnitureId, AnchorType anchorType, boolean playSound) {
|
||||
CustomFurniture furniture = byId(furnitureId);
|
||||
if (furniture == null) return null;
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), playSound);
|
||||
@@ -108,7 +109,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@NotNull
|
||||
public static LoadedFurniture place(Location location, CustomFurniture furniture, AnchorType anchorType, boolean playSound) {
|
||||
public static Furniture place(Location location, CustomFurniture furniture, AnchorType anchorType, boolean playSound) {
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), playSound);
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@Nullable
|
||||
public static LoadedFurniture getLoadedFurnitureByBaseEntity(@NotNull Entity baseEntity) {
|
||||
public static Furniture getLoadedFurnitureByBaseEntity(@NotNull Entity baseEntity) {
|
||||
return BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(baseEntity.getEntityId());
|
||||
}
|
||||
|
||||
@@ -163,7 +164,7 @@ public final class CraftEngineFurniture {
|
||||
* @return the loaded furniture
|
||||
*/
|
||||
@Nullable
|
||||
public static LoadedFurniture getLoadedFurnitureBySeat(@NotNull Entity seat) {
|
||||
public static Furniture getLoadedFurnitureBySeat(@NotNull Entity seat) {
|
||||
Integer baseEntityId = seat.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
|
||||
if (baseEntityId == null) return null;
|
||||
return BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(baseEntityId);
|
||||
@@ -172,107 +173,108 @@ public final class CraftEngineFurniture {
|
||||
/**
|
||||
* Removes furniture
|
||||
*
|
||||
* @param furniture furniture base entity
|
||||
* @param entity furniture base entity
|
||||
* @return success or not
|
||||
*/
|
||||
public static boolean remove(@NotNull Entity furniture) {
|
||||
if (!isFurniture(furniture)) return false;
|
||||
LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(furniture.getEntityId());
|
||||
if (loadedFurniture == null) return false;
|
||||
loadedFurniture.destroy();
|
||||
public static boolean remove(@NotNull Entity entity) {
|
||||
if (!isFurniture(entity)) return false;
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entity.getEntityId());
|
||||
if (furniture == null) return false;
|
||||
furniture.destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture, with more options
|
||||
*
|
||||
* @param furniture furniture base entity
|
||||
* @param entity furniture base entity
|
||||
* @param dropLoot whether to drop loots
|
||||
* @param playSound whether to play break sound
|
||||
* @return success or not
|
||||
*/
|
||||
public static boolean remove(@NotNull Entity furniture,
|
||||
public static boolean remove(@NotNull Entity entity,
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
if (!isFurniture(furniture)) return false;
|
||||
LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(furniture.getEntityId());
|
||||
if (loadedFurniture == null) return false;
|
||||
remove(loadedFurniture, (net.momirealms.craftengine.core.entity.player.Player) null, dropLoot, playSound);
|
||||
if (!isFurniture(entity)) return false;
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entity.getEntityId());
|
||||
if (furniture == null) return false;
|
||||
remove(furniture, (net.momirealms.craftengine.core.entity.player.Player) null, dropLoot, playSound);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture, with more options
|
||||
*
|
||||
* @param furniture furniture base entity
|
||||
* @param entity furniture base entity
|
||||
* @param player the player who removes the furniture
|
||||
* @param dropLoot whether to drop loots
|
||||
* @param playSound whether to play break sound
|
||||
* @return success or not
|
||||
*/
|
||||
public static boolean remove(@NotNull Entity furniture,
|
||||
public static boolean remove(@NotNull Entity entity,
|
||||
@Nullable Player player,
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
if (!isFurniture(furniture)) return false;
|
||||
LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(furniture.getEntityId());
|
||||
if (loadedFurniture == null) return false;
|
||||
remove(loadedFurniture, player, dropLoot, playSound);
|
||||
if (!isFurniture(entity)) return false;
|
||||
Furniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entity.getEntityId());
|
||||
if (furniture == null) return false;
|
||||
remove(furniture, player, dropLoot, playSound);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture by providing furniture instance
|
||||
*
|
||||
* @param loadedFurniture loaded furniture
|
||||
* @param furniture loaded furniture
|
||||
* @param dropLoot whether to drop loots
|
||||
* @param playSound whether to play break sound
|
||||
*/
|
||||
public static void remove(@NotNull LoadedFurniture loadedFurniture,
|
||||
public static void remove(@NotNull Furniture furniture,
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
remove(loadedFurniture, (net.momirealms.craftengine.core.entity.player.Player) null, dropLoot, playSound);
|
||||
remove(furniture, (net.momirealms.craftengine.core.entity.player.Player) null, dropLoot, playSound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture by providing furniture instance
|
||||
*
|
||||
* @param loadedFurniture loaded furniture
|
||||
* @param furniture loaded furniture
|
||||
* @param player the player who removes the furniture
|
||||
* @param dropLoot whether to drop loots
|
||||
* @param playSound whether to play break sound
|
||||
*/
|
||||
|
||||
public static void remove(@NotNull LoadedFurniture loadedFurniture,
|
||||
public static void remove(@NotNull Furniture furniture,
|
||||
@Nullable Player player,
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
remove(loadedFurniture, player == null ? null : BukkitCraftEngine.instance().adapt(player), dropLoot, playSound);
|
||||
remove(furniture, player == null ? null : BukkitCraftEngine.instance().adapt(player), dropLoot, playSound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture by providing furniture instance
|
||||
*
|
||||
* @param loadedFurniture loaded furniture
|
||||
* @param furniture loaded furniture
|
||||
* @param player the player who removes the furniture
|
||||
* @param dropLoot whether to drop loots
|
||||
* @param playSound whether to play break sound
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void remove(@NotNull LoadedFurniture loadedFurniture,
|
||||
public static void remove(@NotNull Furniture furniture,
|
||||
@Nullable net.momirealms.craftengine.core.entity.player.Player player,
|
||||
boolean dropLoot,
|
||||
boolean playSound) {
|
||||
Location location = loadedFurniture.dropLocation();
|
||||
loadedFurniture.destroy();
|
||||
LootTable<ItemStack> lootTable = (LootTable<ItemStack>) loadedFurniture.config().lootTable();
|
||||
if (!furniture.isValid()) return;
|
||||
Location location = ((BukkitFurniture) furniture).dropLocation();
|
||||
furniture.destroy();
|
||||
LootTable<ItemStack> lootTable = (LootTable<ItemStack>) furniture.config().lootTable();
|
||||
World world = new BukkitWorld(location.getWorld());
|
||||
WorldPosition position = new WorldPosition(world, location.getX(), location.getY(), location.getZ());
|
||||
if (dropLoot && lootTable != null) {
|
||||
ContextHolder.Builder builder = ContextHolder.builder()
|
||||
.withParameter(DirectContextParameters.POSITION, position)
|
||||
.withParameter(DirectContextParameters.FURNITURE, loadedFurniture)
|
||||
.withOptionalParameter(DirectContextParameters.FURNITURE_ITEM, loadedFurniture.extraData().item().orElse(null));
|
||||
.withParameter(DirectContextParameters.FURNITURE, furniture)
|
||||
.withOptionalParameter(DirectContextParameters.FURNITURE_ITEM, furniture.extraData().item().orElse(null));
|
||||
if (player != null) {
|
||||
builder.withParameter(DirectContextParameters.PLAYER, player);
|
||||
}
|
||||
@@ -282,7 +284,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
}
|
||||
if (playSound) {
|
||||
world.playBlockSound(position, loadedFurniture.config().settings().sounds().breakSound());
|
||||
world.playBlockSound(position, furniture.config().settings().sounds().breakSound());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.bukkit.api.event;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
@@ -11,10 +12,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class FurnitureBreakEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
private boolean cancelled;
|
||||
private final LoadedFurniture furniture;
|
||||
private final BukkitFurniture furniture;
|
||||
|
||||
public FurnitureBreakEvent(@NotNull Player player,
|
||||
@NotNull LoadedFurniture furniture) {
|
||||
@NotNull BukkitFurniture furniture) {
|
||||
super(player);
|
||||
this.furniture = furniture;
|
||||
}
|
||||
@@ -25,7 +26,7 @@ public class FurnitureBreakEvent extends PlayerEvent implements Cancellable {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LoadedFurniture furniture() {
|
||||
public Furniture furniture() {
|
||||
return this.furniture;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.bukkit.api.event;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -12,12 +13,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class FurnitureInteractEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
private boolean cancelled;
|
||||
private final LoadedFurniture furniture;
|
||||
private final BukkitFurniture furniture;
|
||||
private final InteractionHand hand;
|
||||
private final Location interactionPoint;
|
||||
|
||||
public FurnitureInteractEvent(@NotNull Player player,
|
||||
@NotNull LoadedFurniture furniture,
|
||||
@NotNull BukkitFurniture furniture,
|
||||
@NotNull InteractionHand hand,
|
||||
@NotNull Location interactionPoint) {
|
||||
super(player);
|
||||
@@ -42,7 +43,7 @@ public class FurnitureInteractEvent extends PlayerEvent implements Cancellable {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LoadedFurniture furniture() {
|
||||
public Furniture furniture() {
|
||||
return this.furniture;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.bukkit.api.event;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.Furniture;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -12,12 +13,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class FurniturePlaceEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
private final Location location;
|
||||
private final LoadedFurniture furniture;
|
||||
private final BukkitFurniture furniture;
|
||||
private final InteractionHand hand;
|
||||
private boolean cancelled;
|
||||
|
||||
public FurniturePlaceEvent(@NotNull Player player,
|
||||
@NotNull LoadedFurniture furniture,
|
||||
@NotNull BukkitFurniture furniture,
|
||||
@NotNull Location location,
|
||||
@NotNull InteractionHand hand) {
|
||||
super(player);
|
||||
@@ -32,7 +33,7 @@ public class FurniturePlaceEvent extends PlayerEvent implements Cancellable {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LoadedFurniture furniture() {
|
||||
public Furniture furniture() {
|
||||
return this.furniture;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.furniture.AbstractCustomFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
|
||||
import net.momirealms.craftengine.core.entity.furniture.CustomFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureSettings;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BukkitCustomFurniture extends AbstractCustomFurniture {
|
||||
|
||||
protected BukkitCustomFurniture(@NotNull Key id,
|
||||
@NotNull FurnitureSettings settings,
|
||||
@NotNull Map<AnchorType, Placement> placements,
|
||||
@NotNull Map<EventTrigger, List<Function<PlayerOptionalContext>>> events,
|
||||
@Nullable LootTable<?> lootTable) {
|
||||
super(id, settings, placements, events, lootTable);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new BuilderImpl();
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
private Key id;
|
||||
private Map<AnchorType, Placement> placements;
|
||||
private FurnitureSettings settings;
|
||||
private Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
|
||||
private LootTable<?> lootTable;
|
||||
|
||||
@Override
|
||||
public CustomFurniture build() {
|
||||
return new BukkitCustomFurniture(id, settings, placements, events, lootTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder id(Key id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder placement(Map<AnchorType, Placement> placements) {
|
||||
this.placements = placements;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder settings(FurnitureSettings settings) {
|
||||
this.settings = settings;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder lootTable(LootTable<?> lootTable) {
|
||||
this.lootTable = lootTable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder events(Map<EventTrigger, List<Function<PlayerOptionalContext>>> events) {
|
||||
this.events = events;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LegacyAttributeUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
|
||||
import net.momirealms.craftengine.core.entity.furniture.*;
|
||||
@@ -29,7 +33,7 @@ import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
|
||||
public class LoadedFurniture implements Furniture {
|
||||
public class BukkitFurniture implements Furniture {
|
||||
private final Key id;
|
||||
private final CustomFurniture furniture;
|
||||
private final AnchorType anchorType;
|
||||
@@ -44,8 +48,8 @@ public class LoadedFurniture implements Furniture {
|
||||
// cache
|
||||
private final List<Integer> fakeEntityIds;
|
||||
private final List<Integer> entityIds;
|
||||
private final Map<Integer, HitBox> hitBoxes = new HashMap<>();
|
||||
private final Map<Integer, AABB> aabb = new HashMap<>();
|
||||
private final Map<Integer, HitBox> hitBoxes = new Int2ObjectArrayMap<>();
|
||||
private final Map<Integer, AABB> aabb = new Int2ObjectArrayMap<>();
|
||||
private final boolean minimized;
|
||||
private final boolean hasExternalModel;
|
||||
// seats
|
||||
@@ -55,7 +59,7 @@ public class LoadedFurniture implements Furniture {
|
||||
private Object cachedSpawnPacket;
|
||||
private Object cachedMinimizedSpawnPacket;
|
||||
|
||||
public LoadedFurniture(Entity baseEntity,
|
||||
public BukkitFurniture(Entity baseEntity,
|
||||
CustomFurniture furniture,
|
||||
FurnitureExtraData extraData) {
|
||||
this.id = furniture.id();
|
||||
@@ -66,8 +70,8 @@ public class LoadedFurniture implements Furniture {
|
||||
this.baseEntity = new WeakReference<>(baseEntity);
|
||||
this.furniture = furniture;
|
||||
this.minimized = furniture.settings().minimized();
|
||||
List<Integer> fakeEntityIds = new ArrayList<>();
|
||||
List<Integer> mainEntityIds = new ArrayList<>();
|
||||
List<Integer> fakeEntityIds = new IntArrayList();
|
||||
List<Integer> mainEntityIds = new IntArrayList();
|
||||
mainEntityIds.add(this.baseEntityId);
|
||||
|
||||
CustomFurniture.Placement placement = furniture.getPlacement(anchorType);
|
||||
@@ -84,19 +88,11 @@ public class LoadedFurniture implements Furniture {
|
||||
this.hasExternalModel = false;
|
||||
}
|
||||
|
||||
float yaw = this.location.getYaw();
|
||||
Quaternionf conjugated = QuaternionUtils.toQuaternionf(0, Math.toRadians(180 - yaw), 0).conjugate();
|
||||
|
||||
double x = location.getX();
|
||||
double y = location.getY();
|
||||
double z = location.getZ();
|
||||
|
||||
Quaternionf conjugated = QuaternionUtils.toQuaternionf(0, Math.toRadians(180 - this.location.getYaw()), 0).conjugate();
|
||||
List<Object> packets = new ArrayList<>();
|
||||
List<Object> minimizedPackets = new ArrayList<>();
|
||||
List<Collider> colliders = new ArrayList<>();
|
||||
|
||||
World world = world();
|
||||
WorldPosition position = new WorldPosition(world, x, y, z, yaw, 0);
|
||||
WorldPosition position = position();
|
||||
Integer dyedColor = this.extraData.dyedColor().orElse(null);
|
||||
for (FurnitureElement element : placement.elements()) {
|
||||
int entityId = Reflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
|
||||
@@ -154,13 +150,8 @@ public class LoadedFurniture implements Furniture {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d position() {
|
||||
return new Vec3d(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public World world() {
|
||||
return new BukkitWorld(this.location.getWorld());
|
||||
public WorldPosition position() {
|
||||
return LocationUtils.toWorldPosition(this.location);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -170,7 +161,7 @@ public class LoadedFurniture implements Furniture {
|
||||
|
||||
@NotNull
|
||||
public Entity baseEntity() {
|
||||
Entity entity = baseEntity.get();
|
||||
Entity entity = this.baseEntity.get();
|
||||
if (entity == null) {
|
||||
throw new RuntimeException("Base entity not found. It might be unloaded.");
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.entity.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.ItemDisplayContext;
|
||||
import net.momirealms.craftengine.core.entity.furniture.AbstractFurnitureElement;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureElement;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
@@ -30,10 +31,10 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
|
||||
ItemDisplayContext transform,
|
||||
Vector3f scale,
|
||||
Vector3f translation,
|
||||
Vector3f offset,
|
||||
Vector3f position,
|
||||
Quaternionf rotation,
|
||||
boolean applyDyedColor) {
|
||||
super(item, billboard, transform, scale, translation, offset, rotation, applyDyedColor);
|
||||
super(item, billboard, transform, scale, translation, position, rotation, applyDyedColor);
|
||||
this.commonValues = new ArrayList<>();
|
||||
ItemDisplayEntityData.Scale.addEntityDataIfNotDefaultValue(scale(), this.commonValues);
|
||||
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(rotation(), this.commonValues);
|
||||
@@ -67,4 +68,72 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
|
||||
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), cachedValues);
|
||||
return cachedValues;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new BuilderImpl();
|
||||
}
|
||||
|
||||
public static class BuilderImpl implements Builder {
|
||||
private boolean applyDyedColor;
|
||||
private Key item;
|
||||
private Billboard billboard;
|
||||
private ItemDisplayContext transform;
|
||||
private Vector3f scale;
|
||||
private Vector3f translation;
|
||||
private Vector3f position;
|
||||
private Quaternionf rotation;
|
||||
|
||||
@Override
|
||||
public Builder applyDyedColor(boolean applyDyedColor) {
|
||||
this.applyDyedColor = applyDyedColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder item(Key item) {
|
||||
this.item = item;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder billboard(Billboard billboard) {
|
||||
this.billboard = billboard;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder transform(ItemDisplayContext transform) {
|
||||
this.transform = transform;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder scale(Vector3f scale) {
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder translation(Vector3f translation) {
|
||||
this.translation = translation;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder position(Vector3f position) {
|
||||
this.position = position;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder rotation(Quaternionf rotation) {
|
||||
this.rotation = rotation;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FurnitureElement build() {
|
||||
return new BukkitFurnitureElement(item, billboard, transform, scale, translation, position, rotation, applyDyedColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,58 +6,45 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.handler.FurniturePacketHandler;
|
||||
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.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.entity.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.ItemDisplayContext;
|
||||
import net.momirealms.craftengine.core.entity.furniture.*;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventFunctions;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.sound.SoundData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
public static final NamespacedKey FURNITURE_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:furniture_id"));
|
||||
// DEPRECATED
|
||||
// public static final NamespacedKey FURNITURE_ANCHOR_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:anchor_type"));
|
||||
public static final NamespacedKey FURNITURE_EXTRA_DATA_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:furniture_extra_data"));
|
||||
public static final NamespacedKey FURNITURE_SEAT_BASE_ENTITY_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:seat_to_base_entity"));
|
||||
public static final NamespacedKey FURNITURE_SEAT_VECTOR_3F_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:seat_vector"));
|
||||
public static final NamespacedKey FURNITURE_COLLISION = Objects.requireNonNull(NamespacedKey.fromString("craftengine:collision"));
|
||||
public static final NamespacedKey FURNITURE_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_KEY);
|
||||
public static final NamespacedKey FURNITURE_EXTRA_DATA_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_EXTRA_DATA_KEY);
|
||||
public static final NamespacedKey FURNITURE_SEAT_BASE_ENTITY_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY);
|
||||
public static final NamespacedKey FURNITURE_SEAT_VECTOR_3F_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY);
|
||||
public static final NamespacedKey FURNITURE_COLLISION = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_COLLISION);
|
||||
public static Class<?> COLLISION_ENTITY_CLASS = Interaction.class;
|
||||
public static Object NMS_COLLISION_ENTITY_TYPE = Reflections.instance$EntityType$INTERACTION;
|
||||
public static ColliderType COLLISION_ENTITY_TYPE = ColliderType.INTERACTION;
|
||||
private static BukkitFurnitureManager instance;
|
||||
private final BukkitCraftEngine plugin;
|
||||
private final FurnitureParser furnitureParser;
|
||||
private final Map<Integer, LoadedFurniture> furnitureByRealEntityId = new ConcurrentHashMap<>(256, 0.5f);
|
||||
private final Map<Integer, LoadedFurniture> furnitureByEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
||||
private final Map<Integer, BukkitFurniture> furnitureByRealEntityId = new ConcurrentHashMap<>(256, 0.5f);
|
||||
private final Map<Integer, BukkitFurniture> furnitureByEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
||||
// Event listeners
|
||||
private final Listener dismountListener;
|
||||
private final FurnitureEventListener furnitureEventListener;
|
||||
@@ -67,9 +54,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
|
||||
public BukkitFurnitureManager(BukkitCraftEngine plugin) {
|
||||
super(plugin);
|
||||
instance = this;
|
||||
this.plugin = plugin;
|
||||
this.furnitureParser = new FurnitureParser();
|
||||
this.furnitureEventListener = new FurnitureEventListener(this);
|
||||
this.dismountListener = VersionHelper.isOrAbove1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount);
|
||||
}
|
||||
@@ -79,7 +66,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
return this.place(LocationUtils.toLocation(position), furniture, extraData, playSound);
|
||||
}
|
||||
|
||||
public LoadedFurniture place(Location location, CustomFurniture furniture, FurnitureExtraData extraData, boolean playSound) {
|
||||
public BukkitFurniture place(Location location, CustomFurniture furniture, FurnitureExtraData extraData, boolean playSound) {
|
||||
Optional<AnchorType> optionalAnchorType = extraData.anchorType();
|
||||
if (optionalAnchorType.isEmpty() || !furniture.isAllowedPlacement(optionalAnchorType.get())) {
|
||||
extraData.anchorType(furniture.getAnyPlacement());
|
||||
@@ -101,128 +88,6 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
return loadedFurnitureByRealEntityId(furnitureEntity.getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigParser parser() {
|
||||
return this.furnitureParser;
|
||||
}
|
||||
|
||||
public class FurnitureParser implements ConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] { "furniture" };
|
||||
|
||||
@Override
|
||||
public String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int loadingSequence() {
|
||||
return LoadingSequence.FURNITURE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) {
|
||||
if (byId.containsKey(id)) {
|
||||
throw new LocalizedResourceConfigException("warning.config.furniture.duplicate", path, id);
|
||||
}
|
||||
|
||||
Map<String, Object> lootMap = MiscUtils.castToMap(section.get("loot"), true);
|
||||
Map<String, Object> settingsMap = MiscUtils.castToMap(section.get("settings"), true);
|
||||
Map<String, Object> placementMap = MiscUtils.castToMap(section.get("placement"), true);
|
||||
if (placementMap == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.furniture.missing_placement", path, id);
|
||||
}
|
||||
|
||||
EnumMap<AnchorType, CustomFurniture.Placement> placements = new EnumMap<>(AnchorType.class);
|
||||
|
||||
for (Map.Entry<String, Object> entry : placementMap.entrySet()) {
|
||||
// anchor type
|
||||
AnchorType anchorType = AnchorType.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH));
|
||||
Map<String, Object> placementArguments = MiscUtils.castToMap(entry.getValue(), true);
|
||||
|
||||
Optional<Vector3f> optionalLootSpawnOffset = Optional.ofNullable(placementArguments.get("loot-spawn-offset")).map(it -> MiscUtils.getAsVector3f(it, "loot-spawn-offset"));
|
||||
|
||||
// furniture display elements
|
||||
List<FurnitureElement> elements = new ArrayList<>();
|
||||
List<Map<String, Object>> elementConfigs = (List<Map<String, Object>>) placementArguments.getOrDefault("elements", List.of());
|
||||
for (Map<String, Object> element : elementConfigs) {
|
||||
String key = (String) element.get("item");
|
||||
if (key == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.furniture.element.missing_item", path, id);
|
||||
}
|
||||
ItemDisplayContext transform = ItemDisplayContext.valueOf(element.getOrDefault("transform", "NONE").toString().toUpperCase(Locale.ENGLISH));
|
||||
Billboard billboard = Billboard.valueOf(element.getOrDefault("billboard", "FIXED").toString().toUpperCase(Locale.ENGLISH));
|
||||
FurnitureElement furnitureElement = new BukkitFurnitureElement(Key.of(key), billboard, transform,
|
||||
MiscUtils.getAsVector3f(element.getOrDefault("scale", "1"), "scale"),
|
||||
MiscUtils.getAsVector3f(element.getOrDefault("translation", "0"), "translation"),
|
||||
MiscUtils.getAsVector3f(element.getOrDefault("position", "0"), "position"),
|
||||
MiscUtils.getAsQuaternionf(element.getOrDefault("rotation", "0"), "rotation"),
|
||||
(boolean) element.getOrDefault("apply-dyed-color", true)
|
||||
);
|
||||
elements.add(furnitureElement);
|
||||
}
|
||||
|
||||
// external model providers
|
||||
Optional<ExternalModel> externalModel;
|
||||
if (placementArguments.containsKey("model-engine")) {
|
||||
externalModel = Optional.of(plugin.compatibilityManager().createModelEngineModel(placementArguments.get("model-engine").toString()));
|
||||
} else if (placementArguments.containsKey("better-model")) {
|
||||
externalModel = Optional.of(plugin.compatibilityManager().createBetterModelModel(placementArguments.get("better-model").toString()));
|
||||
} else {
|
||||
externalModel = Optional.empty();
|
||||
}
|
||||
|
||||
// add hitboxes
|
||||
List<Map<String, Object>> hitboxConfigs = (List<Map<String, Object>>) placementArguments.getOrDefault("hitboxes", List.of());
|
||||
List<HitBox> hitboxes = new ArrayList<>();
|
||||
for (Map<String, Object> config : hitboxConfigs) {
|
||||
HitBox hitBox = HitBoxTypes.fromMap(config);
|
||||
hitboxes.add(hitBox);
|
||||
}
|
||||
if (hitboxes.isEmpty() && externalModel.isEmpty()) {
|
||||
hitboxes.add(InteractionHitBox.DEFAULT);
|
||||
}
|
||||
|
||||
// rules
|
||||
Map<String, Object> ruleSection = MiscUtils.castToMap(placementArguments.get("rules"), true);
|
||||
if (ruleSection != null) {
|
||||
RotationRule rotationRule = Optional.ofNullable((String) ruleSection.get("rotation"))
|
||||
.map(it -> RotationRule.valueOf(it.toUpperCase(Locale.ENGLISH)))
|
||||
.orElse(RotationRule.ANY);
|
||||
AlignmentRule alignmentRule = Optional.ofNullable((String) ruleSection.get("alignment"))
|
||||
.map(it -> AlignmentRule.valueOf(it.toUpperCase(Locale.ENGLISH)))
|
||||
.orElse(AlignmentRule.CENTER);
|
||||
placements.put(anchorType, new CustomFurniture.Placement(
|
||||
elements.toArray(new FurnitureElement[0]),
|
||||
hitboxes.toArray(new HitBox[0]),
|
||||
rotationRule,
|
||||
alignmentRule,
|
||||
externalModel,
|
||||
optionalLootSpawnOffset
|
||||
));
|
||||
} else {
|
||||
placements.put(anchorType, new CustomFurniture.Placement(
|
||||
elements.toArray(new FurnitureElement[0]),
|
||||
hitboxes.toArray(new HitBox[0]),
|
||||
RotationRule.ANY,
|
||||
AlignmentRule.CENTER,
|
||||
externalModel,
|
||||
optionalLootSpawnOffset
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// get furniture settings
|
||||
FurnitureSettings settings = FurnitureSettings.fromMap(settingsMap);
|
||||
|
||||
// get loot table
|
||||
LootTable<ItemStack> lootTable = lootMap == null ? null : LootTable.fromMap(lootMap);
|
||||
Map<EventTrigger, List<Function<PlayerOptionalContext>>> events = EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event"));
|
||||
CustomFurniture furniture = new CustomFurniture(id, settings, placements, events, lootTable);
|
||||
byId.put(id, furniture);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayedInit() {
|
||||
COLLISION_ENTITY_CLASS = Config.colliderType() == ColliderType.INTERACTION ? Interaction.class : Boat.class;
|
||||
@@ -264,19 +129,29 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadedFurniture loadedFurnitureByRealEntityId(int entityId) {
|
||||
public BukkitFurniture loadedFurnitureByRealEntityId(int entityId) {
|
||||
return this.furnitureByRealEntityId.get(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public LoadedFurniture loadedFurnitureByEntityId(int entityId) {
|
||||
public BukkitFurniture loadedFurnitureByEntityId(int entityId) {
|
||||
return this.furnitureByEntityId.get(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CustomFurniture.Builder furnitureBuilder() {
|
||||
return BukkitCustomFurniture.builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FurnitureElement.Builder furnitureElementBuilder() {
|
||||
return BukkitFurnitureElement.builder();
|
||||
}
|
||||
|
||||
protected void handleBaseEntityUnload(Entity entity) {
|
||||
int id = entity.getEntityId();
|
||||
LoadedFurniture furniture = this.furnitureByRealEntityId.remove(id);
|
||||
BukkitFurniture furniture = this.furnitureByRealEntityId.remove(id);
|
||||
if (furniture != null) {
|
||||
Location location = entity.getLocation();
|
||||
boolean isPreventing = FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
@@ -305,7 +180,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
if (optionalFurniture.isEmpty()) return;
|
||||
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
BukkitFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
|
||||
Location location = display.getLocation();
|
||||
@@ -313,7 +188,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
boolean preventChange = FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
if (above1_20_1) {
|
||||
if (!preventChange) {
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
BukkitFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
furniture.initializeColliders();
|
||||
for (Player player : display.getTrackedPlayers()) {
|
||||
this.plugin.adapt(player).entityPacketHandlers().computeIfAbsent(furniture.baseEntityId(), k -> new FurniturePacketHandler(furniture.fakeEntityIds()));
|
||||
@@ -321,7 +196,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
BukkitFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
for (Player player : display.getTrackedPlayers()) {
|
||||
this.plugin.adapt(player).entityPacketHandlers().computeIfAbsent(furniture.baseEntityId(), k -> new FurniturePacketHandler(furniture.fakeEntityIds()));
|
||||
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket(player));
|
||||
@@ -383,9 +258,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
Optional<CustomFurniture> optionalFurniture = furnitureById(key);
|
||||
if (optionalFurniture.isPresent()) {
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
BukkitFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
BukkitFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
furniture.initializeColliders(); // safely do it here
|
||||
}
|
||||
}
|
||||
@@ -412,23 +287,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
return FurnitureExtraData.fromBytes(extraData);
|
||||
}
|
||||
|
||||
// private AnchorType getAnchorType(Entity baseEntity, CustomFurniture furniture) {
|
||||
// String anchorType = baseEntity.getPersistentDataContainer().get(FURNITURE_ANCHOR_KEY, PersistentDataType.STRING);
|
||||
// if (anchorType != null) {
|
||||
// try {
|
||||
// AnchorType unverified = AnchorType.valueOf(anchorType);
|
||||
// if (furniture.isAllowedPlacement(unverified)) {
|
||||
// return unverified;
|
||||
// }
|
||||
// } catch (IllegalArgumentException ignored) {
|
||||
// }
|
||||
// }
|
||||
// AnchorType anchorTypeEnum = furniture.getAnyPlacement();
|
||||
// baseEntity.getPersistentDataContainer().set(FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, anchorTypeEnum.name());
|
||||
// return anchorTypeEnum;
|
||||
// }
|
||||
|
||||
private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture) {
|
||||
private synchronized BukkitFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture) {
|
||||
FurnitureExtraData extraData;
|
||||
try {
|
||||
extraData = getFurnitureExtraData(display);
|
||||
@@ -436,16 +295,21 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
extraData = FurnitureExtraData.builder().build();
|
||||
plugin.logger().warn("Furniture extra data could not be loaded", e);
|
||||
}
|
||||
LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, extraData);
|
||||
this.furnitureByRealEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture);
|
||||
for (int entityId : loadedFurniture.entityIds()) {
|
||||
this.furnitureByEntityId.put(entityId, loadedFurniture);
|
||||
BukkitFurniture bukkitFurniture = new BukkitFurniture(display, furniture, extraData);
|
||||
this.furnitureByRealEntityId.put(bukkitFurniture.baseEntityId(), bukkitFurniture);
|
||||
for (int entityId : bukkitFurniture.entityIds()) {
|
||||
this.furnitureByEntityId.put(entityId, bukkitFurniture);
|
||||
}
|
||||
for (Collider collisionEntity : loadedFurniture.collisionEntities()) {
|
||||
for (Collider collisionEntity : bukkitFurniture.collisionEntities()) {
|
||||
int collisionEntityId = FastNMS.INSTANCE.method$Entity$getId(collisionEntity.handle());
|
||||
this.furnitureByRealEntityId.put(collisionEntityId, loadedFurniture);
|
||||
this.furnitureByRealEntityId.put(collisionEntityId, bukkitFurniture);
|
||||
}
|
||||
return loadedFurniture;
|
||||
return bukkitFurniture;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HitBox defaultHitBox() {
|
||||
return InteractionHitBox.DEFAULT;
|
||||
}
|
||||
|
||||
protected void handleDismount(Player player, Entity entity) {
|
||||
@@ -458,7 +322,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
Integer baseFurniture = vehicle.getPersistentDataContainer().get(FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
|
||||
if (baseFurniture == null) return;
|
||||
vehicle.remove();
|
||||
LoadedFurniture furniture = loadedFurnitureByRealEntityId(baseFurniture);
|
||||
BukkitFurniture furniture = loadedFurnitureByRealEntityId(baseFurniture);
|
||||
if (furniture == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ 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.BukkitFurnitureManager;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||
@@ -134,7 +134,7 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
|
||||
Item<?> item = context.getItem();
|
||||
|
||||
LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().place(
|
||||
BukkitFurniture bukkitFurniture = BukkitFurnitureManager.instance().place(
|
||||
furnitureLocation.clone(), customFurniture,
|
||||
FurnitureExtraData.builder()
|
||||
.item(item.copyWithCount(1))
|
||||
@@ -142,15 +142,15 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
.dyedColor(item.dyedColor().orElse(null))
|
||||
.build(), false);
|
||||
|
||||
FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, loadedFurniture, furnitureLocation, context.getHand());
|
||||
FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, bukkitFurniture, furnitureLocation, context.getHand());
|
||||
if (EventUtils.fireAndCheckCancel(placeEvent)) {
|
||||
loadedFurniture.destroy();
|
||||
bukkitFurniture.destroy();
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
Cancellable dummy = Cancellable.dummy();
|
||||
PlayerOptionalContext functionContext = PlayerOptionalContext.of(player, ContextHolder.builder()
|
||||
.withParameter(DirectContextParameters.FURNITURE, loadedFurniture)
|
||||
.withParameter(DirectContextParameters.FURNITURE, bukkitFurniture)
|
||||
.withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(furnitureLocation))
|
||||
.withParameter(DirectContextParameters.EVENT, dummy)
|
||||
.withParameter(DirectContextParameters.HAND, context.getHand())
|
||||
|
||||
@@ -121,7 +121,14 @@ public class ItemEventListener implements Listener {
|
||||
|
||||
// interact block with items
|
||||
if (hasItem && action == Action.RIGHT_CLICK_BLOCK) {
|
||||
Location interactionPoint = Objects.requireNonNull(event.getInteractionPoint(), "interaction point should not be null");
|
||||
Location interactionPoint = event.getInteractionPoint();
|
||||
// some plugins would trigger this event without interaction point
|
||||
if (interactionPoint == null) {
|
||||
if (hasCustomItem) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Direction direction = DirectionUtils.toDirection(event.getBlockFace());
|
||||
BlockPos pos = LocationUtils.toBlockPos(block.getLocation());
|
||||
Vec3d vec3d = new Vec3d(interactionPoint.getX(), interactionPoint.getY(), interactionPoint.getZ());
|
||||
|
||||
@@ -11,7 +11,7 @@ import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent;
|
||||
import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent;
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.projectile.BukkitProjectileManager;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
@@ -1489,7 +1489,7 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> PICK_ITEM_FROM_ENTITY = (user, event, packet) -> {
|
||||
try {
|
||||
int entityId = (int) Reflections.field$ServerboundPickItemFromEntityPacket$id.get(packet);
|
||||
LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
if (furniture == null) return;
|
||||
Player player = (Player) user.platformPlayer();
|
||||
if (player == null) return;
|
||||
@@ -1518,7 +1518,7 @@ public class PacketConsumers {
|
||||
}
|
||||
};
|
||||
|
||||
private static void handlePickItemFromEntityOnMainThread(Player player, LoadedFurniture furniture) throws Exception {
|
||||
private static void handlePickItemFromEntityOnMainThread(Player player, BukkitFurniture furniture) throws Exception {
|
||||
Key itemId = furniture.config().settings().itemId();
|
||||
if (itemId == null) return;
|
||||
pickItem(player, itemId, null, FastNMS.INSTANCE.method$CraftEntity$getHandle(furniture.baseEntity()));
|
||||
@@ -1596,7 +1596,7 @@ public class PacketConsumers {
|
||||
int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet);
|
||||
if (entityType == Reflections.instance$EntityType$ITEM_DISPLAY) {
|
||||
// Furniture
|
||||
LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
|
||||
if (furniture != null) {
|
||||
user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(furniture.fakeEntityIds()));
|
||||
user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false);
|
||||
@@ -1606,7 +1606,7 @@ public class PacketConsumers {
|
||||
}
|
||||
} else if (entityType == BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE) {
|
||||
// Cancel collider entity packet
|
||||
LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
|
||||
if (furniture != null) {
|
||||
event.setCancelled(true);
|
||||
user.entityPacketHandlers().put(entityId, FurnitureCollisionPacketHandler.INSTANCE);
|
||||
@@ -1670,7 +1670,7 @@ public class PacketConsumers {
|
||||
} else {
|
||||
entityId = FastNMS.INSTANCE.field$ServerboundInteractPacket$entityId(packet);
|
||||
}
|
||||
LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
if (furniture == null) return;
|
||||
Object action = Reflections.field$ServerboundInteractPacket$action.get(packet);
|
||||
Object actionType = Reflections.method$ServerboundInteractPacket$Action$getType.invoke(action);
|
||||
@@ -1694,7 +1694,7 @@ public class PacketConsumers {
|
||||
// execute functions
|
||||
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
|
||||
.withParameter(DirectContextParameters.FURNITURE, furniture)
|
||||
.withParameter(DirectContextParameters.POSITION, new WorldPosition(furniture.world(), furniture.position()))
|
||||
.withParameter(DirectContextParameters.POSITION, furniture.position())
|
||||
);
|
||||
furniture.config().execute(context, EventTrigger.LEFT_CLICK);
|
||||
furniture.config().execute(context, EventTrigger.BREAK);
|
||||
@@ -1724,7 +1724,7 @@ public class PacketConsumers {
|
||||
// execute functions
|
||||
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
|
||||
.withParameter(DirectContextParameters.FURNITURE, furniture)
|
||||
.withParameter(DirectContextParameters.POSITION, new WorldPosition(furniture.world(), furniture.position()))
|
||||
.withParameter(DirectContextParameters.POSITION, furniture.position())
|
||||
);
|
||||
furniture.config().execute(context, EventTrigger.RIGHT_CLICK);;
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractCustomFurniture implements CustomFurniture {
|
||||
private final Key id;
|
||||
private final FurnitureSettings settings;
|
||||
private final Map<AnchorType, Placement> placements;
|
||||
private final Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
|
||||
@Nullable
|
||||
private final LootTable<?> lootTable;
|
||||
|
||||
private final AnchorType anyType;
|
||||
|
||||
protected AbstractCustomFurniture(@NotNull Key id,
|
||||
@NotNull FurnitureSettings settings,
|
||||
@NotNull Map<AnchorType, Placement> placements,
|
||||
@NotNull Map<EventTrigger, List<Function<PlayerOptionalContext>>> events,
|
||||
@Nullable LootTable<?> lootTable) {
|
||||
this.id = id;
|
||||
this.settings = settings;
|
||||
this.placements = placements;
|
||||
this.lootTable = lootTable;
|
||||
this.events = events;
|
||||
this.anyType = placements.keySet().stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(PlayerOptionalContext context, EventTrigger trigger) {
|
||||
for (Function<PlayerOptionalContext> function : Optional.ofNullable(this.events.get(trigger)).orElse(Collections.emptyList())) {
|
||||
function.run(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<AnchorType, Placement> placements() {
|
||||
return this.placements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FurnitureSettings settings() {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable LootTable<?> lootTable() {
|
||||
return this.lootTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnchorType getAnyPlacement() {
|
||||
return this.anyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedPlacement(AnchorType anchorType) {
|
||||
return this.placements.containsKey(anchorType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Placement getPlacement(AnchorType anchorType) {
|
||||
return this.placements.get(anchorType);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public abstract class AbstractFurnitureElement implements FurnitureElement {
|
||||
private final ItemDisplayContext transform;
|
||||
private final Vector3f scale;
|
||||
private final Vector3f translation;
|
||||
private final Vector3f offset;
|
||||
private final Vector3f position;
|
||||
private final Quaternionf rotation;
|
||||
private final boolean applyDyedColor;
|
||||
|
||||
@@ -21,7 +21,7 @@ public abstract class AbstractFurnitureElement implements FurnitureElement {
|
||||
ItemDisplayContext transform,
|
||||
Vector3f scale,
|
||||
Vector3f translation,
|
||||
Vector3f offset,
|
||||
Vector3f position,
|
||||
Quaternionf rotation,
|
||||
boolean applyDyedColor) {
|
||||
this.billboard = billboard;
|
||||
@@ -30,7 +30,7 @@ public abstract class AbstractFurnitureElement implements FurnitureElement {
|
||||
this.translation = translation;
|
||||
this.item = item;
|
||||
this.rotation = rotation;
|
||||
this.offset = offset;
|
||||
this.position = position;
|
||||
this.applyDyedColor = applyDyedColor;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,6 @@ public abstract class AbstractFurnitureElement implements FurnitureElement {
|
||||
|
||||
@Override
|
||||
public Vector3f position() {
|
||||
return offset;
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.ItemDisplayContext;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventFunctions;
|
||||
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.ResourceConfigUtils;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
protected final Map<Key, CustomFurniture> byId = new HashMap<>();
|
||||
private final CraftEngine plugin;
|
||||
private final FurnitureParser furnitureParser;
|
||||
// Cached command suggestions
|
||||
private final List<Suggestion> cachedSuggestions = new ArrayList<>();
|
||||
|
||||
public AbstractFurnitureManager(CraftEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
this.furnitureParser = new FurnitureParser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigParser parser() {
|
||||
return this.furnitureParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayedLoad() {
|
||||
this.initSuggestions();
|
||||
@@ -37,4 +62,104 @@ public abstract class AbstractFurnitureManager implements FurnitureManager {
|
||||
public void unload() {
|
||||
this.byId.clear();
|
||||
}
|
||||
|
||||
protected abstract HitBox defaultHitBox();
|
||||
|
||||
protected abstract FurnitureElement.Builder furnitureElementBuilder();
|
||||
|
||||
protected abstract CustomFurniture.Builder furnitureBuilder();
|
||||
|
||||
public class FurnitureParser implements ConfigParser {
|
||||
public static final String[] CONFIG_SECTION_NAME = new String[] { "furniture" };
|
||||
|
||||
@Override
|
||||
public String[] sectionId() {
|
||||
return CONFIG_SECTION_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int loadingSequence() {
|
||||
return LoadingSequence.FURNITURE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) {
|
||||
if (byId.containsKey(id)) {
|
||||
throw new LocalizedResourceConfigException("warning.config.furniture.duplicate", path, id);
|
||||
}
|
||||
|
||||
EnumMap<AnchorType, CustomFurniture.Placement> placements = new EnumMap<>(AnchorType.class);
|
||||
Map<String, Object> placementMap = MiscUtils.castToMap(ResourceConfigUtils.requireNonNullOrThrow(section.get("placement"), "warning.config.furniture.missing_placement"), false);
|
||||
for (Map.Entry<String, Object> entry : placementMap.entrySet()) {
|
||||
// anchor type
|
||||
AnchorType anchorType = AnchorType.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH));
|
||||
Map<String, Object> placementArguments = MiscUtils.castToMap(entry.getValue(), false);
|
||||
Optional<Vector3f> optionalLootSpawnOffset = Optional.ofNullable(placementArguments.get("loot-spawn-offset")).map(it -> MiscUtils.getAsVector3f(it, "loot-spawn-offset"));
|
||||
// furniture display elements
|
||||
List<FurnitureElement> elements = new ArrayList<>();
|
||||
List<Map<String, Object>> elementConfigs = (List<Map<String, Object>>) placementArguments.getOrDefault("elements", List.of());
|
||||
for (Map<String, Object> element : elementConfigs) {
|
||||
FurnitureElement furnitureElement = furnitureElementBuilder()
|
||||
.item(Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(element.get("item"), "warning.config.furniture.element.missing_item")))
|
||||
.applyDyedColor((boolean) element.getOrDefault("apply-dyed-color", true))
|
||||
.billboard(ResourceConfigUtils.getOrDefault(element.get("billboard"), o -> Billboard.valueOf(o.toString().toUpperCase(Locale.ENGLISH)), Billboard.FIXED))
|
||||
.transform(ResourceConfigUtils.getOrDefault(element.get("transform"), o -> ItemDisplayContext.valueOf(o.toString().toUpperCase(Locale.ENGLISH)), ItemDisplayContext.NONE))
|
||||
.scale(MiscUtils.getAsVector3f(element.getOrDefault("scale", "1"), "scale"))
|
||||
.position(MiscUtils.getAsVector3f(element.getOrDefault("position", "0"), "position"))
|
||||
.translation(MiscUtils.getAsVector3f(element.getOrDefault("translation", "0"), "translation"))
|
||||
.rotation(MiscUtils.getAsQuaternionf(element.getOrDefault("rotation", "0"), "rotation"))
|
||||
.build();
|
||||
elements.add(furnitureElement);
|
||||
}
|
||||
|
||||
// external model providers
|
||||
Optional<ExternalModel> externalModel;
|
||||
if (placementArguments.containsKey("model-engine")) {
|
||||
externalModel = Optional.of(plugin.compatibilityManager().createModelEngineModel(placementArguments.get("model-engine").toString()));
|
||||
} else if (placementArguments.containsKey("better-model")) {
|
||||
externalModel = Optional.of(plugin.compatibilityManager().createBetterModelModel(placementArguments.get("better-model").toString()));
|
||||
} else {
|
||||
externalModel = Optional.empty();
|
||||
}
|
||||
|
||||
// add hitboxes
|
||||
List<HitBox> hitboxes = ResourceConfigUtils.parseConfigAsList(placementArguments.get("hitboxes"), HitBoxTypes::fromMap);
|
||||
if (hitboxes.isEmpty() && externalModel.isEmpty()) {
|
||||
hitboxes.add(defaultHitBox());
|
||||
}
|
||||
|
||||
// rules
|
||||
Map<String, Object> ruleSection = MiscUtils.castToMap(placementArguments.get("rules"), true);
|
||||
if (ruleSection != null) {
|
||||
placements.put(anchorType, new CustomFurniture.Placement(
|
||||
elements.toArray(new FurnitureElement[0]),
|
||||
hitboxes.toArray(new HitBox[0]),
|
||||
ResourceConfigUtils.getOrDefault(ruleSection.get("rotation"), o -> RotationRule.valueOf(o.toString().toUpperCase(Locale.ENGLISH)), RotationRule.ANY),
|
||||
ResourceConfigUtils.getOrDefault(ruleSection.get("alignment"), o -> AlignmentRule.valueOf(o.toString().toUpperCase(Locale.ENGLISH)), AlignmentRule.CENTER),
|
||||
externalModel,
|
||||
optionalLootSpawnOffset
|
||||
));
|
||||
} else {
|
||||
placements.put(anchorType, new CustomFurniture.Placement(
|
||||
elements.toArray(new FurnitureElement[0]),
|
||||
hitboxes.toArray(new HitBox[0]),
|
||||
RotationRule.ANY,
|
||||
AlignmentRule.CENTER,
|
||||
externalModel,
|
||||
optionalLootSpawnOffset
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
CustomFurniture furniture = furnitureBuilder()
|
||||
.id(id)
|
||||
.settings(FurnitureSettings.fromMap(MiscUtils.castToMap(section.get("settings"), true)))
|
||||
.placement(placements)
|
||||
.events(EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event")))
|
||||
.lootTable(LootTable.fromMap(MiscUtils.castToMap(section.get("loot"), true)))
|
||||
.build();
|
||||
AbstractFurnitureManager.this.byId.put(id, furniture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,74 +5,53 @@ import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.context.function.Function;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CustomFurniture {
|
||||
private final Key id;
|
||||
private final FurnitureSettings settings;
|
||||
private final EnumMap<AnchorType, Placement> placements;
|
||||
private final AnchorType anyType;
|
||||
private final Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
|
||||
@Nullable
|
||||
private final LootTable<?> lootTable;
|
||||
// TODO 家具的设计存在问题。家具也应该存在不同的状态,而不是根据放置规则直接决定状态类型
|
||||
public interface CustomFurniture {
|
||||
|
||||
public CustomFurniture(@NotNull Key id,
|
||||
@NotNull FurnitureSettings settings,
|
||||
@NotNull EnumMap<AnchorType, Placement> placements,
|
||||
@NotNull Map<EventTrigger, List<Function<PlayerOptionalContext>>> events,
|
||||
@Nullable LootTable<?> lootTable) {
|
||||
this.id = id;
|
||||
this.settings = settings;
|
||||
this.placements = placements;
|
||||
this.lootTable = lootTable;
|
||||
this.events = events;
|
||||
this.anyType = placements.keySet().stream().findFirst().orElse(null);
|
||||
}
|
||||
void execute(PlayerOptionalContext context, EventTrigger trigger);
|
||||
|
||||
public void execute(PlayerOptionalContext context, EventTrigger trigger) {
|
||||
for (Function<PlayerOptionalContext> function : Optional.ofNullable(this.events.get(trigger)).orElse(Collections.emptyList())) {
|
||||
function.run(context);
|
||||
}
|
||||
}
|
||||
Key id();
|
||||
|
||||
public Key id() {
|
||||
return id;
|
||||
}
|
||||
Map<AnchorType, Placement> placements();
|
||||
|
||||
public EnumMap<AnchorType, Placement> placements() {
|
||||
return placements;
|
||||
}
|
||||
|
||||
public FurnitureSettings settings() {
|
||||
return settings;
|
||||
}
|
||||
FurnitureSettings settings();
|
||||
|
||||
@Nullable
|
||||
public LootTable<?> lootTable() {
|
||||
return lootTable;
|
||||
LootTable<?> lootTable();
|
||||
|
||||
AnchorType getAnyPlacement();
|
||||
|
||||
boolean isAllowedPlacement(AnchorType anchorType);
|
||||
|
||||
Placement getPlacement(AnchorType anchorType);
|
||||
|
||||
interface Builder {
|
||||
|
||||
Builder id(Key id);
|
||||
|
||||
Builder placement(Map<AnchorType, Placement> placements);
|
||||
|
||||
Builder settings(FurnitureSettings settings);
|
||||
|
||||
Builder lootTable(LootTable<?> lootTable);
|
||||
|
||||
Builder events(Map<EventTrigger, List<Function<PlayerOptionalContext>>> events);
|
||||
|
||||
CustomFurniture build();
|
||||
}
|
||||
|
||||
public AnchorType getAnyPlacement() {
|
||||
return this.anyType;
|
||||
}
|
||||
|
||||
public boolean isAllowedPlacement(AnchorType anchorType) {
|
||||
return placements.containsKey(anchorType);
|
||||
}
|
||||
|
||||
public Placement getPlacement(AnchorType anchorType) {
|
||||
return placements.get(anchorType);
|
||||
}
|
||||
|
||||
public record Placement(FurnitureElement[] elements,
|
||||
HitBox[] hitBoxes,
|
||||
RotationRule rotationRule,
|
||||
AlignmentRule alignmentRule,
|
||||
Optional<ExternalModel> externalModel,
|
||||
Optional<Vector3f> dropOffset) {
|
||||
record Placement(FurnitureElement[] elements,
|
||||
HitBox[] hitBoxes,
|
||||
RotationRule rotationRule,
|
||||
AlignmentRule alignmentRule,
|
||||
Optional<ExternalModel> externalModel,
|
||||
Optional<Vector3f> dropOffset) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@@ -13,9 +14,7 @@ import java.util.UUID;
|
||||
public interface Furniture {
|
||||
void initializeColliders();
|
||||
|
||||
Vec3d position();
|
||||
|
||||
World world();
|
||||
WorldPosition position();
|
||||
|
||||
boolean isValid();
|
||||
|
||||
|
||||
@@ -29,4 +29,25 @@ public interface FurnitureElement {
|
||||
Vector3f position();
|
||||
|
||||
void initPackets(int entityId, @NotNull WorldPosition position, @NotNull Quaternionf conjugated, @Nullable Integer dyedColor, Consumer<Object> packets);
|
||||
|
||||
interface Builder {
|
||||
|
||||
Builder item(Key item);
|
||||
|
||||
Builder billboard(Billboard billboard);
|
||||
|
||||
Builder transform(ItemDisplayContext transform);
|
||||
|
||||
Builder scale(Vector3f scale);
|
||||
|
||||
Builder translation(Vector3f translation);
|
||||
|
||||
Builder position(Vector3f position);
|
||||
|
||||
Builder rotation(Quaternionf rotation);
|
||||
|
||||
Builder applyDyedColor(boolean applyDyedColor);
|
||||
|
||||
FurnitureElement build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,12 @@ import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface FurnitureManager extends Manageable {
|
||||
Key FURNITURE_KEY = Key.of("craftengine:furniture_id");
|
||||
Key FURNITURE_EXTRA_DATA_KEY = Key.of("craftengine:furniture_extra_data");
|
||||
Key FURNITURE_SEAT_BASE_ENTITY_KEY = Key.of("craftengine:seat_to_base_entity");
|
||||
Key FURNITURE_SEAT_VECTOR_3F_KEY = Key.of("craftengine:seat_vector");
|
||||
Key FURNITURE_COLLISION = Key.of("craftengine:collision");
|
||||
|
||||
String FURNITURE_ADMIN_NODE = "craftengine.furniture.admin";
|
||||
|
||||
ConfigParser parser();
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.util;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedException;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -15,6 +16,10 @@ public final class ResourceConfigUtils {
|
||||
|
||||
private ResourceConfigUtils() {}
|
||||
|
||||
public static <T, O> T getOrDefault(@Nullable O raw, Function<O, T> function, T defaultValue) {
|
||||
return raw != null ? function.apply(raw) : defaultValue;
|
||||
}
|
||||
|
||||
public static <T> T requireNonNullOrThrow(T obj, String node) {
|
||||
if (obj == null)
|
||||
throw new LocalizedResourceConfigException(node);
|
||||
|
||||
@@ -71,9 +71,9 @@ modmenu_version=13.0.3
|
||||
cloth_version=17.0.144
|
||||
|
||||
# Proxy settings
|
||||
#systemProp.socks.proxyHost=127.0.0.1
|
||||
#systemProp.socks.proxyPort=7890
|
||||
#systemProp.http.proxyHost=127.0.0.1
|
||||
#systemProp.http.proxyPort=7890
|
||||
#systemProp.https.proxyHost=127.0.0.1
|
||||
#systemProp.https.proxyPort=7890
|
||||
systemProp.socks.proxyHost=127.0.0.1
|
||||
systemProp.socks.proxyPort=7890
|
||||
systemProp.http.proxyHost=127.0.0.1
|
||||
systemProp.http.proxyPort=7890
|
||||
systemProp.https.proxyHost=127.0.0.1
|
||||
systemProp.https.proxyPort=7890
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("com.gradleup.shadow") version "9.0.0-beta13"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.16"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("com.gradleup.shadow") version "9.0.0-beta13"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.16"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("com.gradleup.shadow") version "9.0.0-beta13"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.16"
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17"
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
Reference in New Issue
Block a user