mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-27 19:09:08 +00:00
修改家具存储方案
This commit is contained in:
@@ -41,7 +41,7 @@ items:
|
||||
- 0,0,-0.1 0
|
||||
- 1,0,-0.1 0
|
||||
loot:
|
||||
template: "default:loot_table/basic"
|
||||
template: "default:loot_table/furniture"
|
||||
arguments:
|
||||
item: default:bench
|
||||
default:table_lamp:
|
||||
@@ -92,7 +92,7 @@ items:
|
||||
height: 0.4
|
||||
interactive: true
|
||||
loot:
|
||||
template: "default:loot_table/basic"
|
||||
template: "default:loot_table/furniture"
|
||||
arguments:
|
||||
item: default:table_lamp
|
||||
default:wooden_chair:
|
||||
@@ -132,6 +132,6 @@ items:
|
||||
seats:
|
||||
- 0,0,-0.1 0
|
||||
loot:
|
||||
template: "default:loot_table/basic"
|
||||
template: "default:loot_table/furniture"
|
||||
arguments:
|
||||
item: default:wooden_chair
|
||||
@@ -968,6 +968,18 @@ templates#loot_tables:
|
||||
- type: item
|
||||
item: "{item}"
|
||||
|
||||
# drop the original furniture item or a fallback item
|
||||
|
||||
# template: default:loot_table/furniture
|
||||
# arguments:
|
||||
# item: the fallback item
|
||||
default:loot_table/furniture:
|
||||
pools:
|
||||
- rolls: 1
|
||||
entries:
|
||||
- type: furniture_item
|
||||
item: "{item}"
|
||||
|
||||
# drop with silk touch
|
||||
|
||||
# template: default:loot_table/silk_touch
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
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.FurnitureExtraData;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.loot.LootTable;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
@@ -41,7 +42,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
|
||||
/**
|
||||
* Places furniture at the certain location
|
||||
* Places furniture at certain location
|
||||
*
|
||||
* @param location location
|
||||
* @param furnitureId furniture to place
|
||||
@@ -55,7 +56,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
|
||||
/**
|
||||
* Places furniture at the certain location
|
||||
* Places furniture at certain location
|
||||
*
|
||||
* @param location location
|
||||
* @param furnitureId furniture to place
|
||||
@@ -66,11 +67,11 @@ public final class CraftEngineFurniture {
|
||||
public static LoadedFurniture place(Location location, Key furnitureId, AnchorType anchorType) {
|
||||
CustomFurniture furniture = byId(furnitureId);
|
||||
if (furniture == null) return null;
|
||||
return BukkitFurnitureManager.instance().place(furniture, location, anchorType, true);
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places furniture at the certain location
|
||||
* Places furniture at certain location
|
||||
*
|
||||
* @param location location
|
||||
* @param furniture furniture to place
|
||||
@@ -79,11 +80,11 @@ public final class CraftEngineFurniture {
|
||||
*/
|
||||
@NotNull
|
||||
public static LoadedFurniture place(Location location, CustomFurniture furniture, AnchorType anchorType) {
|
||||
return BukkitFurnitureManager.instance().place(furniture, location, anchorType, true);
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places furniture at the certain location
|
||||
* Places furniture at certain location
|
||||
*
|
||||
* @param location location
|
||||
* @param furnitureId furniture to place
|
||||
@@ -95,11 +96,11 @@ public final class CraftEngineFurniture {
|
||||
public static LoadedFurniture place(Location location, Key furnitureId, AnchorType anchorType, boolean playSound) {
|
||||
CustomFurniture furniture = byId(furnitureId);
|
||||
if (furniture == null) return null;
|
||||
return BukkitFurnitureManager.instance().place(furniture, location, anchorType, playSound);
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), playSound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places furniture at the certain location
|
||||
* Places furniture at certain location
|
||||
*
|
||||
* @param location location
|
||||
* @param furniture furniture to place
|
||||
@@ -109,7 +110,7 @@ public final class CraftEngineFurniture {
|
||||
*/
|
||||
@NotNull
|
||||
public static LoadedFurniture place(Location location, CustomFurniture furniture, AnchorType anchorType, boolean playSound) {
|
||||
return BukkitFurnitureManager.instance().place(furniture, location, anchorType, playSound);
|
||||
return BukkitFurnitureManager.instance().place(location, furniture, FurnitureExtraData.builder().anchorType(anchorType).build(), playSound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +223,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture by providing a plugin furniture instance
|
||||
* Removes furniture by providing furniture instance
|
||||
*
|
||||
* @param loadedFurniture loaded furniture
|
||||
* @param dropLoot whether to drop loots
|
||||
@@ -235,7 +236,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture by providing a plugin furniture instance
|
||||
* Removes furniture by providing furniture instance
|
||||
*
|
||||
* @param loadedFurniture loaded furniture
|
||||
* @param player the player who removes the furniture
|
||||
@@ -251,7 +252,7 @@ public final class CraftEngineFurniture {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes furniture by providing a plugin furniture instance
|
||||
* Removes furniture by providing furniture instance
|
||||
*
|
||||
* @param loadedFurniture loaded furniture
|
||||
* @param player the player who removes the furniture
|
||||
@@ -272,6 +273,7 @@ public final class CraftEngineFurniture {
|
||||
ContextHolder.Builder builder = ContextHolder.builder();
|
||||
builder.withParameter(CommonParameters.LOCATION, vec3d);
|
||||
builder.withParameter(CommonParameters.WORLD, world);
|
||||
builder.withOptionalParameter(CommonParameters.FURNITURE_ITEM, loadedFurniture.extraData().item().orElse(null));
|
||||
if (player != null) {
|
||||
builder.withParameter(CommonParameters.PLAYER, player);
|
||||
//mark item builder.withOptionalParameter(CommonParameters.MAIN_HAND_ITEM, player.getItemInHand(InteractionHand.MAIN_HAND));
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.entity.Billboard;
|
||||
import net.momirealms.craftengine.core.entity.ItemDisplayContext;
|
||||
@@ -20,7 +21,7 @@ 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.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -31,13 +32,16 @@ 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.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
public static final NamespacedKey FURNITURE_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:furniture_id"));
|
||||
public static final NamespacedKey FURNITURE_ANCHOR_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:anchor_type"));
|
||||
// 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"));
|
||||
@@ -66,19 +70,23 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Furniture place(CustomFurniture furniture, Vec3d vec3d, net.momirealms.craftengine.core.world.World world, AnchorType anchorType, boolean playSound) {
|
||||
return this.place(furniture, new Location((World) world.platformWorld(), vec3d.x(), vec3d.y(), vec3d.z()), anchorType, playSound);
|
||||
public Furniture place(WorldPosition position, CustomFurniture furniture, FurnitureExtraData extraData, boolean playSound) {
|
||||
return this.place(LocationUtils.toLocation(position), furniture, extraData, playSound);
|
||||
}
|
||||
|
||||
public LoadedFurniture place(CustomFurniture furniture, Location location, AnchorType anchorType, boolean playSound) {
|
||||
if (furniture.isAllowedPlacement(anchorType)) {
|
||||
anchorType = furniture.getAnyPlacement();
|
||||
public LoadedFurniture 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());
|
||||
}
|
||||
AnchorType finalAnchorType = anchorType;
|
||||
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());
|
||||
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, finalAnchorType.name());
|
||||
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) {
|
||||
@@ -224,9 +232,6 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(interaction);
|
||||
} else if (entity instanceof Boat boat) {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(boat);
|
||||
} else if (entity instanceof Shulker shulker) {
|
||||
// TODO 移除这一行,预计过一个月
|
||||
handleCollisionEntityLoadOnEntitiesLoad(shulker);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,7 +306,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, getAnchorType(display, customFurniture));
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
furniture.initializeColliders();
|
||||
for (Player player : display.getTrackedPlayers()) {
|
||||
this.plugin.adapt(player).entityPacketHandlers().computeIfAbsent(furniture.baseEntityId(), k -> new FurniturePacketHandler(furniture.fakeEntityIds()));
|
||||
@@ -309,7 +314,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(display, customFurniture));
|
||||
LoadedFurniture 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));
|
||||
@@ -373,7 +378,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(display, customFurniture));
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture);
|
||||
furniture.initializeColliders(); // safely do it here
|
||||
}
|
||||
}
|
||||
@@ -394,24 +399,37 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
collisionEntity.remove();
|
||||
}
|
||||
|
||||
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 FurnitureExtraData getFurnitureExtraData(Entity baseEntity) throws IOException {
|
||||
byte[] extraData = baseEntity.getPersistentDataContainer().get(FURNITURE_EXTRA_DATA_KEY, PersistentDataType.BYTE_ARRAY);
|
||||
if (extraData == null) return FurnitureExtraData.builder().build();
|
||||
return FurnitureExtraData.fromBytes(extraData);
|
||||
}
|
||||
|
||||
private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture, AnchorType anchorType) {
|
||||
LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, anchorType);
|
||||
// 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) {
|
||||
FurnitureExtraData extraData;
|
||||
try {
|
||||
extraData = getFurnitureExtraData(display);
|
||||
} catch (IOException e) {
|
||||
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);
|
||||
|
||||
@@ -31,6 +31,7 @@ public class LoadedFurniture implements Furniture {
|
||||
private final Key id;
|
||||
private final CustomFurniture furniture;
|
||||
private final AnchorType anchorType;
|
||||
private final FurnitureExtraData extraData;
|
||||
// location
|
||||
private final Location location;
|
||||
// base entity
|
||||
@@ -54,10 +55,11 @@ public class LoadedFurniture implements Furniture {
|
||||
|
||||
public LoadedFurniture(Entity baseEntity,
|
||||
CustomFurniture furniture,
|
||||
AnchorType anchorType) {
|
||||
FurnitureExtraData extraData) {
|
||||
this.id = furniture.id();
|
||||
this.extraData = extraData;
|
||||
this.baseEntityId = baseEntity.getEntityId();
|
||||
this.anchorType = anchorType;
|
||||
this.anchorType = extraData.anchorType().orElse(furniture.getAnyPlacement());
|
||||
this.location = baseEntity.getLocation();
|
||||
this.baseEntity = new WeakReference<>(baseEntity);
|
||||
this.furniture = furniture;
|
||||
@@ -305,6 +307,11 @@ public class LoadedFurniture implements Furniture {
|
||||
spawnSeatEntityForPlayer((Player) player.platformPlayer(), seat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FurnitureExtraData extraData() {
|
||||
return this.extraData;
|
||||
}
|
||||
|
||||
public void spawnSeatEntityForPlayer(org.bukkit.entity.Player player, Seat seat) {
|
||||
Location location = this.calculateSeatLocation(seat);
|
||||
Entity seatEntity = seat.limitPlayerRotation() ?
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.item;
|
||||
|
||||
import com.saicone.rtag.item.ItemTagStream;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BoneMealItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||
@@ -163,6 +164,11 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
HandlerList.unregisterAll(this.debugStickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<ItemStack> fromByteArray(byte[] bytes) {
|
||||
return this.factory.wrap(ItemTagStream.INSTANCE.fromBytes(bytes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigParser parser() {
|
||||
return this.itemParser;
|
||||
|
||||
@@ -71,7 +71,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
|
||||
|
||||
@Override
|
||||
public ItemWrapper<ItemStack> copyWithCount(int count) {
|
||||
ItemStack copied = item.clone();
|
||||
ItemStack copied = this.item.clone();
|
||||
copied.setAmount(count);
|
||||
return new ComponentItemWrapper(copied);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public class ComponentTypes {
|
||||
public static final Object REPAIR_COST = getComponentType(ComponentKeys.REPAIR_COST);
|
||||
public static final Object CUSTOM_DATA = getComponentType(ComponentKeys.CUSTOM_DATA);
|
||||
public static final Object PROFILE = getComponentType(ComponentKeys.PROFILE);
|
||||
public static final Object DYED_COLOR = getComponentType(ComponentKeys.DYED_COLOR);
|
||||
|
||||
private ComponentTypes() {}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.EventUtils;
|
||||
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
|
||||
import net.momirealms.craftengine.core.entity.furniture.CustomFurniture;
|
||||
import net.momirealms.craftengine.core.entity.furniture.FurnitureExtraData;
|
||||
import net.momirealms.craftengine.core.entity.furniture.HitBox;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
@@ -126,7 +127,15 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().place(customFurniture, furnitureLocation.clone(), anchorType, false);
|
||||
Item<?> item = context.getItem();
|
||||
|
||||
LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().place(
|
||||
furnitureLocation.clone(), customFurniture,
|
||||
FurnitureExtraData.builder()
|
||||
.item(item.copyWithCount(1))
|
||||
.anchorType(anchorType)
|
||||
.dyedColor(item.dyedColor().orElse(-1))
|
||||
.build(), false);
|
||||
|
||||
FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, loadedFurniture, furnitureLocation, context.getHand());
|
||||
if (EventUtils.fireAndCheckCancel(placeEvent)) {
|
||||
@@ -135,7 +144,6 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
||||
}
|
||||
|
||||
if (!player.isCreativeMode()) {
|
||||
Item<?> item = context.getItem();
|
||||
item.count(item.count() - 1);
|
||||
item.load();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.bukkit.item.factory;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.saicone.rtag.item.ItemTagStream;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemTags;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.item.EquipmentData;
|
||||
@@ -46,6 +47,11 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] toByteArray(W item) {
|
||||
return ItemTagStream.INSTANCE.toBytes(item.getItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isBlockItem(W item) {
|
||||
return item.getItem().getType().isBlock();
|
||||
|
||||
@@ -244,6 +244,26 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> dyedColor(ComponentItemWrapper item) {
|
||||
if (!item.hasComponent(ComponentTypes.DYED_COLOR)) return Optional.empty();
|
||||
return Optional.ofNullable(
|
||||
(Integer) ComponentType.encodeJava(
|
||||
ComponentTypes.DYED_COLOR,
|
||||
item.getComponent(ComponentTypes.DYED_COLOR)
|
||||
).orElse(null)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dyedColor(ComponentItemWrapper item, Integer color) {
|
||||
if (color == null) {
|
||||
item.resetComponent(ComponentTypes.DYED_COLOR);
|
||||
} else {
|
||||
item.setJavaComponent(ComponentTypes.DYED_COLOR, color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> maxDamage(ComponentItemWrapper item) {
|
||||
if (!item.hasComponent(ComponentTypes.MAX_DAMAGE)) return Optional.of((int) item.getItem().getType().getMaxDurability());
|
||||
|
||||
@@ -152,6 +152,21 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
|
||||
item.set(damage, "Damage");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> dyedColor(LegacyItemWrapper item) {
|
||||
if (!item.hasTag("display", "color")) return Optional.empty();
|
||||
return Optional.of(item.get("display", "color"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dyedColor(LegacyItemWrapper item, Integer color) {
|
||||
if (color == null) {
|
||||
item.remove("display", "color");
|
||||
} else {
|
||||
item.set(color, "display", "color");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<Integer> maxDamage(LegacyItemWrapper item) {
|
||||
return Optional.of((int) item.getItem().getType().getMaxDurability());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture;
|
||||
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
|
||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
@@ -55,7 +56,7 @@ public class DebugSpawnFurnitureCommand extends BukkitCommandFeature<CommandSend
|
||||
CustomFurniture customFurniture = optionalCustomFurniture.get();
|
||||
AnchorType anchorType = (AnchorType) context.optional("anchor-type").orElse(customFurniture.getAnyPlacement());
|
||||
boolean playSound = context.flags().hasFlag("silent");
|
||||
furnitureManager.place(customFurniture, location, anchorType, !playSound);
|
||||
CraftEngineFurniture.place(location, customFurniture, anchorType, playSound);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockTags;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bukkit.data.BlockPredicate;
|
||||
import org.incendo.cloud.bukkit.parser.BlockPredicateParser;
|
||||
import org.incendo.cloud.bukkit.parser.NamespacedKeyParser;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.standard.BooleanParser;
|
||||
import org.incendo.cloud.parser.standard.ByteParser;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
|
||||
@@ -3,13 +3,19 @@ package net.momirealms.craftengine.bukkit.util;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LocationUtils {
|
||||
|
||||
private LocationUtils() {}
|
||||
|
||||
public static Location toLocation(WorldPosition position) {
|
||||
return new Location((World) position.world().platformWorld(), position.position().x(), position.position().y(), position.position().z());
|
||||
}
|
||||
|
||||
public static Vec3d toVec3d(Location loc) {
|
||||
return new Vec3d(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
|
||||
@@ -46,4 +46,6 @@ public interface Furniture {
|
||||
boolean hasExternalModel();
|
||||
|
||||
void spawnSeatEntityForPlayer(Player player, Seat seat);
|
||||
|
||||
FurnitureExtraData extraData();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package net.momirealms.craftengine.core.entity.furniture;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.NBT;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class FurnitureExtraData {
|
||||
public static final String ITEM = "item";
|
||||
public static final String DYED_COLOR = "dyed_color";
|
||||
public static final String ANCHOR_TYPE = "anchor_type";
|
||||
|
||||
private final CompoundTag data;
|
||||
|
||||
public FurnitureExtraData(CompoundTag data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Optional<Item<?>> item() {
|
||||
byte[] data = this.data.getByteArray(ITEM);
|
||||
if (data == null) return Optional.empty();
|
||||
return Optional.of(CraftEngine.instance().itemManager().fromByteArray(data));
|
||||
}
|
||||
|
||||
public Optional<Integer> dyedColor() {
|
||||
if (this.data.containsKey(DYED_COLOR)) return Optional.of(this.data.getInt(DYED_COLOR));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<AnchorType> anchorType() {
|
||||
if (this.data.containsKey(ANCHOR_TYPE)) return Optional.of(AnchorType.byId(this.data.getInt(ANCHOR_TYPE)));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public FurnitureExtraData anchorType(AnchorType type) {
|
||||
this.data.putInt(ANCHOR_TYPE, type.getId());
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static FurnitureExtraData fromBytes(final byte[] data) throws IOException {
|
||||
return new FurnitureExtraData(NBT.fromBytes(data));
|
||||
}
|
||||
|
||||
public static byte[] toBytes(final FurnitureExtraData data) throws IOException {
|
||||
return NBT.toBytes(data.data);
|
||||
}
|
||||
|
||||
public byte[] toBytes() throws IOException {
|
||||
return toBytes(this);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final CompoundTag data;
|
||||
|
||||
public Builder() {
|
||||
this.data = new CompoundTag();
|
||||
}
|
||||
|
||||
public Builder item(Item<?> item) {
|
||||
this.data.putByteArray(ITEM, item.toByteArray());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder dyedColor(int color) {
|
||||
if (color < 0) return this;
|
||||
this.data.putInt(DYED_COLOR, color);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder anchorType(AnchorType type) {
|
||||
this.data.putInt(ANCHOR_TYPE, type.getId());
|
||||
return this;
|
||||
}
|
||||
|
||||
public FurnitureExtraData build() {
|
||||
return new FurnitureExtraData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,7 @@ 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;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.WorldPosition;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -21,7 +20,7 @@ public interface FurnitureManager extends Manageable {
|
||||
|
||||
Collection<Suggestion> cachedSuggestions();
|
||||
|
||||
Furniture place(CustomFurniture furniture, Vec3d vec3d, World world, AnchorType anchorType, boolean playSound);
|
||||
Furniture place(WorldPosition position, CustomFurniture furniture, FurnitureExtraData extraData, boolean playSound);
|
||||
|
||||
Optional<CustomFurniture> furnitureById(Key id);
|
||||
|
||||
|
||||
@@ -93,6 +93,17 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
return this.factory.maxDamage(this.item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> dyedColor(Integer data) {
|
||||
this.factory.dyedColor(this.item, data);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> dyedColor() {
|
||||
return this.factory.dyedColor(this.item);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Optional<CustomItem<I>> getCustomItem() {
|
||||
@@ -358,4 +369,9 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
public void merge(Item<I> another) {
|
||||
this.factory.merge(this.item, (W) ((AbstractItem) another).item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
return this.factory.toByteArray(this.item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,5 @@ public class ComponentKeys {
|
||||
public static final Key REPAIR_COST = Key.of("minecraft", "repair_cost");
|
||||
public static final Key CUSTOM_DATA = Key.of("minecraft", "custom_data");
|
||||
public static final Key PROFILE = Key.of("minecraft", "profile");
|
||||
public static final Key DYED_COLOR = Key.of("minecraft", "dyed_color");
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@ public interface Item<I> {
|
||||
|
||||
Optional<Integer> maxDamage();
|
||||
|
||||
Item<I> dyedColor(Integer data);
|
||||
|
||||
Optional<Integer> dyedColor();
|
||||
|
||||
Item<I> customName(String displayName);
|
||||
|
||||
Optional<String> customName();
|
||||
@@ -145,4 +149,6 @@ public interface Item<I> {
|
||||
Item<I> mergeCopy(Item<?> another);
|
||||
|
||||
void merge(Item<I> another);
|
||||
|
||||
byte[] toByteArray();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,10 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
|
||||
protected abstract void damage(W item, Integer damage);
|
||||
|
||||
protected abstract Optional<Integer> dyedColor(W item);
|
||||
|
||||
protected abstract void dyedColor(W item, Integer color);
|
||||
|
||||
protected abstract Optional<Integer> maxDamage(W item);
|
||||
|
||||
protected abstract void maxDamage(W item, Integer damage);
|
||||
@@ -138,4 +142,7 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
protected abstract void equippable(W item, EquipmentData data);
|
||||
|
||||
protected abstract Optional<EquipmentData> equippable(W item);
|
||||
|
||||
protected abstract byte[] toByteArray(W item);
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
|
||||
Item<T> wrap(T itemStack);
|
||||
|
||||
Item<T> fromByteArray(byte[] bytes);
|
||||
|
||||
Collection<Key> items();
|
||||
|
||||
Key itemId(T itemStack);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package net.momirealms.craftengine.core.loot.entry;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.loot.LootConditions;
|
||||
import net.momirealms.craftengine.core.loot.LootContext;
|
||||
import net.momirealms.craftengine.core.loot.function.LootFunction;
|
||||
import net.momirealms.craftengine.core.loot.function.LootFunctions;
|
||||
import net.momirealms.craftengine.core.plugin.context.Condition;
|
||||
import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class FurnitureItemLootEntryContainer<T> extends SingleItemLootEntryContainer<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final boolean hasFallback;
|
||||
|
||||
protected FurnitureItemLootEntryContainer(@Nullable Key item, List<Condition<LootContext>> conditions, List<LootFunction<T>> lootFunctions, int weight, int quality) {
|
||||
super(item, conditions, lootFunctions, weight, quality);
|
||||
this.hasFallback = item != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return LootEntryContainers.FURNITURE_ITEM;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void createItem(Consumer<Item<T>> lootConsumer, LootContext context) {
|
||||
Optional<Item<?>> optionalItem = context.getOptionalParameter(CommonParameters.FURNITURE_ITEM);
|
||||
if (optionalItem.isPresent()) {
|
||||
lootConsumer.accept((Item<T>) optionalItem.get());
|
||||
} else if (this.hasFallback) {
|
||||
super.createItem(lootConsumer, context);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory<A> implements LootEntryContainerFactory<A> {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public LootEntryContainer<A> create(Map<String, Object> arguments) {
|
||||
Key item = Optional.ofNullable(arguments.get("item")).map(String::valueOf).map(Key::of).orElse(null);
|
||||
int weight = ResourceConfigUtils.getAsInt(arguments.getOrDefault("weight", 1), "weight");
|
||||
int quality = ResourceConfigUtils.getAsInt(arguments.getOrDefault("quality", 0), "quality");
|
||||
List<Condition<LootContext>> conditions = Optional.ofNullable(arguments.get("conditions"))
|
||||
.map(it -> LootConditions.fromMapList((List<Map<String, Object>>) it))
|
||||
.orElse(Collections.emptyList());
|
||||
List<LootFunction<A>> functions = Optional.ofNullable(arguments.get("functions"))
|
||||
.map(it -> (List<LootFunction<A>>) new ArrayList<LootFunction<A>>(LootFunctions.fromMapList((List<Map<String, Object>>) it)))
|
||||
.orElse(Collections.emptyList());
|
||||
return new FurnitureItemLootEntryContainer<>(item, conditions, functions, weight, quality);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,14 @@ import java.util.Map;
|
||||
public class LootEntryContainers {
|
||||
public static final Key ALTERNATIVES = Key.from("craftengine:alternatives");
|
||||
public static final Key ITEM = Key.from("craftengine:item");
|
||||
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
||||
public static final Key EXP = Key.from("craftengine:exp");
|
||||
|
||||
static {
|
||||
register(ALTERNATIVES, AlternativesLootEntryContainer.FACTORY);
|
||||
register(ITEM, SingleItemLootEntryContainer.FACTORY);
|
||||
register(EXP, ExpLootEntryContainer.FACTORY);
|
||||
register(FURNITURE_ITEM, FurnitureItemLootEntryContainer.FACTORY);
|
||||
}
|
||||
|
||||
public static <T> void register(Key key, LootEntryContainerFactory<T> factory) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.plugin.context.parameter;
|
||||
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextKey;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
@@ -13,6 +14,7 @@ public final class CommonParameters {
|
||||
public static final ContextKey<Double> LAST_RANDOM = ContextKey.of("last_random");
|
||||
public static final ContextKey<Vec3d> LOCATION = ContextKey.of("location");
|
||||
public static final ContextKey<World> WORLD = ContextKey.of("world");
|
||||
public static final ContextKey<Item<?>> FURNITURE_ITEM = ContextKey.of("furniture_item");
|
||||
public static final ContextKey<Boolean> FALLING_BLOCK = ContextKey.of("falling_block");
|
||||
public static final ContextKey<Float> EXPLOSION_RADIUS = ContextKey.of("explosion_radius");
|
||||
public static final ContextKey<Player> PLAYER = ContextKey.of("player");
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.momirealms.craftengine.core.world;
|
||||
|
||||
public class WorldPosition {
|
||||
private final World world;
|
||||
private final Position position;
|
||||
|
||||
public WorldPosition(Position position, World world) {
|
||||
this.position = position;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public Position position() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public World world() {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ asm_version=9.8
|
||||
asm_commons_version=9.8
|
||||
jar_relocator_version=1.7
|
||||
adventure_bundle_version=4.21.0
|
||||
adventure_platform_version=4.3.4
|
||||
adventure_platform_version=4.4.0
|
||||
cloud_core_version=2.0.0
|
||||
cloud_services_version=2.0.0
|
||||
cloud_brigadier_version=2.0.0-beta.10
|
||||
|
||||
Reference in New Issue
Block a user