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

refactor(bukkit): 实现配置并且优化性能

This commit is contained in:
jhqwqmc
2025-05-10 18:32:07 +08:00
parent 29b0c9c8c5
commit 79244af744
8 changed files with 111 additions and 210 deletions

View File

@@ -48,7 +48,6 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
return CompletableFuture.completedFuture(plugin().itemManager().cachedSuggestions());
}
}))
.required("interpolationDuration", IntegerParser.integerParser())
.required("displayType", ByteParser.byteParser((byte) 0, (byte) 8))
.required("translation", StringParser.stringParser())
.required("rotationLeft", StringParser.stringParser())
@@ -57,12 +56,6 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
NamespacedKey namespacedKey = context.get("id");
ItemStack item = new ItemStack(Material.TRIDENT);
item.editMeta((meta) -> {
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(CustomTridentUtils.customTridentKey, PersistentDataType.STRING, namespacedKey.asString());
container.set(CustomTridentUtils.interpolationDurationaKey, PersistentDataType.INTEGER, context.get("interpolationDuration"));
container.set(CustomTridentUtils.displayTypeKey, PersistentDataType.BYTE, context.get("displayType"));
container.set(CustomTridentUtils.translationKey, PersistentDataType.STRING, context.get("translation"));
container.set(CustomTridentUtils.rotationLeftKey, PersistentDataType.STRING, context.get("rotationLeft"));
Item<ItemStack> ceItem = BukkitItemManager.instance().createWrappedItem(Key.of(namespacedKey.asString()), null);
Optional<Integer> customModelData = ceItem.customModelData();
customModelData.ifPresent(meta::setCustomModelData);

View File

@@ -1621,7 +1621,7 @@ public class PacketConsumers {
try {
int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentPositionSync(event, packet, entityId);
event.replacePacket(CustomTridentUtils.buildCustomTridentPositionSync(packet, entityId));
return;
}
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
@@ -2345,7 +2345,7 @@ public class PacketConsumers {
try {
int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentMove(packet);
event.replacePacket(CustomTridentUtils.buildCustomTridentMove(packet, entityId));
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e);

View File

@@ -4,6 +4,8 @@ import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.network.NMSPacketEvent;
import net.momirealms.craftengine.core.entity.CustomTrident;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
@@ -12,74 +14,51 @@ import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class CustomTridentUtils {
public static final NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident"));
public static final NamespacedKey interpolationDurationaKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:interpolation_duration"));
public static final NamespacedKey displayTypeKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:display_type"));
public static final NamespacedKey translationKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:translation"));
public static final NamespacedKey rotationLeftKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:rotation_left"));
public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) throws IllegalAccessException {
public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) {
int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet);
Trident trident = getTridentById(user, entityId);
if (trident == null) return;
World world = trident.getWorld();
Object serverEntity;
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(trident);
Object tracker = Reflections.field$Entity$trackedEntity.get(nmsEntity);
if (tracker != null) {
serverEntity = Reflections.field$ChunkMap$TrackedEntity$serverEntity.get(tracker);
} else {
serverEntity = null;
}
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity);
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
if (notCustomTrident(trident)) return;
modifyCustomTridentPacket(packet);
Object newPacket = modifyCustomTridentPacket(packet, entityId);
List<Object> itemDisplayValues = buildEntityDataValues(trident);
user.tridentView().put(entityId, itemDisplayValues);
user.sendPacket(packet, true);
user.sendPacket(newPacket, true);
user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true);
event.setCancelled(true);
if (serverEntity != null) {
// 这里直接暴力更新
SchedulerTask task = CraftEngine.instance().scheduler().asyncRepeating(() -> {
try {
Reflections.method$ServerEntity$sendChanges.invoke(serverEntity);
if (!isInGround(nmsEntity)) {
world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0);
}
} catch (IllegalAccessException | InvocationTargetException e) {
CraftEngine.instance().logger().warn("Failed to send entity data packet", e);
FastNMS.INSTANCE.method$ServerEntity$sendChanges(serverEntity);
if (canSpawnParticle(nmsEntity)) {
world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0);
}
}, 0, 5, TimeUnit.MILLISECONDS);
user.tridentTaskView().put(entityId, task);
}
}
private static boolean isInGround(Object nmsEntity) throws IllegalAccessException, InvocationTargetException {
if (!Reflections.field$Entity$wasTouchingWater.getBoolean(nmsEntity)) return true;
if (VersionHelper.isOrAbove1_21_2()) {
return (boolean) Reflections.method$AbstractArrow$isInGround.invoke(nmsEntity);
} else {
return Reflections.field$AbstractArrow$inGround.getBoolean(nmsEntity);
}
private static boolean canSpawnParticle(Object nmsEntity) {
if (!FastNMS.INSTANCE.field$AbstractArrow$wasTouchingWater(nmsEntity)) return false;
return !FastNMS.INSTANCE.method$AbstractArrow$isInGround(nmsEntity);
}
@Nullable
@@ -92,62 +71,75 @@ public class CustomTridentUtils {
public static boolean notCustomTrident(Trident trident) {
if (trident == null) return true;
PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer();
String customTrident = container.get(customTridentKey, PersistentDataType.STRING);
return customTrident == null;
Optional<CustomItem<ItemStack>> customItem = BukkitItemManager.instance().wrap(trident.getItemStack()).getCustomItem();
return customItem.map(itemStackCustomItem -> itemStackCustomItem.settings().customTrident() == null).orElse(true);
}
public static void modifyCustomTridentPacket(Object packet) throws IllegalAccessException {
float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$yRot.getByte(packet));
float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$xRot.getByte(packet));
Reflections.field$ClientboundAddEntityPacket$type.set(packet, Reflections.instance$EntityType$ITEM_DISPLAY);
Reflections.field$ClientboundAddEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot));
Reflections.field$ClientboundAddEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F)));
public static Object modifyCustomTridentPacket(Object packet, int entityId) {
UUID uuid = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$uuid(packet);
double x = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$x(packet);
double y = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$y(packet);
double z = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$z(packet);
float yRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$yRot(packet);
float xRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$xRot(packet);
Object type = Reflections.instance$EntityType$ITEM_DISPLAY;
int data = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$data(packet);
double xa = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$xa(packet);
double ya = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$ya(packet);
double za = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$za(packet);
double yHeadRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$yHeadRot(packet);
return FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId, uuid, x, y, z,
MCUtils.clamp(-xRot, -90.0F, 90.0F), -yRot,
type, data, FastNMS.INSTANCE.constructor$Vec3(xa, ya, za), yHeadRot
);
}
public static List<Object> buildEntityDataValues(Trident trident) {
List<Object> itemDisplayValues = new ArrayList<>();
ItemStack itemStack = trident.getItemStack();
PersistentDataContainer container = itemStack.getItemMeta().getPersistentDataContainer();
String customTrident = container.getOrDefault(customTridentKey, PersistentDataType.STRING, "craftengine:empty");
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(Key.of(customTrident), null);
Optional<CustomItem<ItemStack>> customItem = BukkitItemManager.instance().wrap(itemStack).getCustomItem();
if (customItem.isEmpty()) return itemDisplayValues;
CustomTrident customTrident = customItem.get().settings().customTrident();
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(customTrident.customTridentItemId(), null);
itemStack.getEnchantments().forEach((enchantment, level) -> item.addEnchantment(new Enchantment(Key.of(enchantment.getKey().toString()), level)));
Integer interpolationDurationa = container.getOrDefault(interpolationDurationaKey, PersistentDataType.INTEGER, 2);
Byte displayType = container.getOrDefault(displayTypeKey, PersistentDataType.BYTE, (byte) 0);
String translation = container.getOrDefault(translationKey, PersistentDataType.STRING, "0+0+0");
String[] translations = translation.split("\\+");
String rotationLeft = container.getOrDefault(rotationLeftKey, PersistentDataType.STRING, "0+0+0+0");
String[] rotationLefts = rotationLeft.split("\\+");
ItemDisplayEntityData.InterpolationDelay.addEntityDataIfNotDefaultValue(-1, itemDisplayValues);
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(new Vector3f(Float.parseFloat(translations[0]), Float.parseFloat(translations[1]), Float.parseFloat(translations[2])), itemDisplayValues);
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(new Quaternionf(Float.parseFloat(rotationLefts[0]), Float.parseFloat(rotationLefts[1]), Float.parseFloat(rotationLefts[2]), Float.parseFloat(rotationLefts[3])), itemDisplayValues);
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(customTrident.translation(), itemDisplayValues);
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(customTrident.rotationLefts(), itemDisplayValues);
if (VersionHelper.isOrAbove1_20_2()) {
ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues);
ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues);
ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues);
ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues);
} else {
ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues);
ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues);
}
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), itemDisplayValues);
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(displayType, itemDisplayValues);
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(customTrident.displayType(), itemDisplayValues);
return itemDisplayValues;
}
public static void modifyCustomTridentPositionSync(NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException {
Object positionMoveRotation = Reflections.field$ClientboundEntityPositionSyncPacket$values.get(packet);
boolean onGround = Reflections.field$ClientboundEntityPositionSyncPacket$onGround.getBoolean(packet);
Object position = Reflections.field$PositionMoveRotation$position.get(positionMoveRotation);
Object deltaMovement = Reflections.field$PositionMoveRotation$deltaMovement.get(positionMoveRotation);
float yRot = Reflections.field$PositionMoveRotation$yRot.getFloat(positionMoveRotation);
float xRot = Reflections.field$PositionMoveRotation$xRot.getFloat(positionMoveRotation);
Object newPositionMoveRotation = Reflections.constructor$PositionMoveRotation.newInstance(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F));
event.replacePacket(Reflections.constructor$ClientboundEntityPositionSyncPacket.newInstance(entityId, newPositionMoveRotation, onGround));
public static Object buildCustomTridentPositionSync(Object packet, int entityId) {
Object positionMoveRotation = FastNMS.INSTANCE.field$ClientboundEntityPositionSyncPacket$values(packet);
boolean onGround = FastNMS.INSTANCE.field$ClientboundEntityPositionSyncPacket$onGround(packet);
Object position = FastNMS.INSTANCE.field$PositionMoveRotation$position(positionMoveRotation);
Object deltaMovement = FastNMS.INSTANCE.field$PositionMoveRotation$deltaMovement(positionMoveRotation);
float yRot = FastNMS.INSTANCE.field$PositionMoveRotation$yRot(positionMoveRotation);
float xRot = FastNMS.INSTANCE.field$PositionMoveRotation$xRot(positionMoveRotation);
Object newPositionMoveRotation = FastNMS.INSTANCE.constructor$PositionMoveRotation(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F));
return FastNMS.INSTANCE.constructor$ClientboundEntityPositionSyncPacket(entityId, newPositionMoveRotation, onGround);
}
public static void modifyCustomTridentMove(Object packet) throws IllegalAccessException {
float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$xRot.getByte(packet));
float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$yRot.getByte(packet));
Reflections.field$ClientboundMoveEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F)));
Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot));
public static Object buildCustomTridentMove(Object packet, int entityId) {
short xa = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xa(packet);
short ya = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$ya(packet);
short za = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$za(packet);
float xRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xRot(packet));
float yRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$yRot(packet));
boolean onGround = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$onGround(packet);
return FastNMS.INSTANCE.constructor$ClientboundMoveEntityPacket$PosRot(
entityId, xa, ya, za,
MCUtils.packDegrees(-yRot), MCUtils.packDegrees(MCUtils.clamp(-xRot, -90.0F, 90.0F)),
onGround
);
}
public static List<Object> buildCustomTridentSetEntityDataPacket(NetWorkUser user, List<Object> packedItems, int entityId) {

View File

@@ -6632,130 +6632,4 @@ public class Reflections {
)
);
public static final Field field$ClientboundSetEntityDataPacket$id = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundSetEntityDataPacket, int.class, 0
)
);
public static final Class<?> clazz$PositionMoveRotation =
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.entity.PositionMoveRotation")
);
public static final Constructor<?> constructor$PositionMoveRotation = Optional.ofNullable(clazz$PositionMoveRotation)
.map(ReflectionUtils::getTheOnlyConstructor)
.orElse(null);
public static final Field field$ClientboundEntityPositionSyncPacket$values = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$PositionMoveRotation, 0))
.orElse(null);
public static final Field field$ClientboundEntityPositionSyncPacket$onGround = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, boolean.class, 0))
.orElse(null);
public static final Field field$PositionMoveRotation$position = Optional.ofNullable(clazz$PositionMoveRotation)
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$Vec3, 0))
.orElse(null);
public static final Field field$PositionMoveRotation$deltaMovement = Optional.ofNullable(clazz$PositionMoveRotation)
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$Vec3, 1))
.orElse(null);
public static final Field field$PositionMoveRotation$yRot = Optional.ofNullable(clazz$PositionMoveRotation)
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, float.class, 0))
.orElse(null);
public static final Field field$PositionMoveRotation$xRot = Optional.ofNullable(clazz$PositionMoveRotation)
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, float.class, 1))
.orElse(null);
public static final Constructor<?> constructor$ClientboundEntityPositionSyncPacket = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
.map(ReflectionUtils::getTheOnlyConstructor)
.orElse(null);
public static final Field field$ClientboundAddEntityPacket$xRot = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundAddEntityPacket, byte.class, 0
)
);
public static final Field field$ClientboundAddEntityPacket$yRot = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundAddEntityPacket, byte.class, 1
)
);
public static final Field field$ClientboundMoveEntityPacket$xRot = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, byte.class, 1
)
);
public static final Field field$ClientboundMoveEntityPacket$yRot = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, byte.class, 0
)
);
public static final Class<?> clazz$ServerEntity = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"server.level.EntityTrackerEntry",
"server.level.ServerEntity"
)
);
public static final Method method$ServerEntity$sendChanges = requireNonNull(
ReflectionUtils.getMethod(
clazz$ServerEntity, void.class, new String[]{ "sendChanges", "a" }
)
);
public static final Class<?> clazz$ChunkMap$TrackedEntity = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"server.level.PlayerChunkMap$EntityTracker",
"server.level.ChunkMap$TrackedEntity"
)
);
public static final Field field$Entity$trackedEntity = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$Entity, clazz$ChunkMap$TrackedEntity, 0
)
);
public static final Field field$ChunkMap$TrackedEntity$serverEntity = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ChunkMap$TrackedEntity, clazz$ServerEntity, 0
)
);
public static final Field field$Entity$wasTouchingWater = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$Entity, VersionHelper.isOrAbove1_21_2()
? new String[]{ "wasTouchingWater", "ag" } : VersionHelper.isOrAbove1_20_5()
? new String[]{ "wasTouchingWater", "aj" } : VersionHelper.isOrAbove1_20_2()
? new String[]{ "wasTouchingWater", "ai" } : new String[]{ "wasTouchingWater", "ah" }
)
);
public static final Class<?> clazz$AbstractArrow = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.entity.projectile.EntityArrow",
"world.entity.projectile.AbstractArrow"
)
);
// 1.20~1.21.1
public static final Field field$AbstractArrow$inGround =
ReflectionUtils.getDeclaredField(
clazz$AbstractArrow, boolean.class, 0
);
// 1.21.2+
public static final Method method$AbstractArrow$isInGround =
ReflectionUtils.getMethod(
clazz$AbstractArrow, boolean.class, VersionHelper.isOrAbove1_21_5() ? new String[]{ "isInGround", "e" } : new String[]{ "isInGround", "l" }
);
}

View File

@@ -0,0 +1,8 @@
package net.momirealms.craftengine.core.entity;
import net.momirealms.craftengine.core.util.Key;
import org.joml.Quaternionf;
import org.joml.Vector3f;
public record CustomTrident(Key customTridentItemId, Byte displayType, Vector3f translation, Quaternionf rotationLefts) {
}

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.core.item;
import net.momirealms.craftengine.core.entity.CustomTrident;
import net.momirealms.craftengine.core.item.modifier.EquippableModifier;
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration;
@@ -9,6 +10,8 @@ import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.*;
import java.util.stream.Collectors;
@@ -22,6 +25,7 @@ public class ItemSettings {
List<AnvilRepairItem> anvilRepairItems = List.of();
boolean renameable = true;
boolean canPlaceRelatedVanillaBlock = false;
CustomTrident customTrident;
private ItemSettings() {}
@@ -50,6 +54,7 @@ public class ItemSettings {
newSettings.anvilRepairItems = settings.anvilRepairItems;
newSettings.renameable = settings.renameable;
newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock;
newSettings.customTrident = settings.customTrident;
return newSettings;
}
@@ -65,6 +70,10 @@ public class ItemSettings {
return settings;
}
public CustomTrident customTrident() {
return customTrident;
}
public boolean canPlaceRelatedVanillaBlock() {
return canPlaceRelatedVanillaBlock;
}
@@ -109,6 +118,11 @@ public class ItemSettings {
return this;
}
public ItemSettings customTrident(CustomTrident customTrident) {
this.customTrident = customTrident;
return this;
}
public ItemSettings canPlaceRelatedVanillaBlock(boolean canPlaceRelatedVanillaBlock) {
this.canPlaceRelatedVanillaBlock = canPlaceRelatedVanillaBlock;
return this;
@@ -193,6 +207,14 @@ public class ItemSettings {
boolean bool = (boolean) value;
return settings -> settings.canPlaceRelatedVanillaBlock(bool);
}));
registerFactory("custom-trident", (value -> {
Map<String, Object> args = MiscUtils.castToMap(value, false);
Key customTridentItemId = Key.of(args.get("custom-trident-item").toString());
Byte displayType = Byte.valueOf(args.get("display-type").toString());
Vector3f translation = MiscUtils.getAsVector3f(args.get("translation"), "translation");
Quaternionf rotationLefts = MiscUtils.getAsQuaternionf(args.get("rotation-left"), "rotation-left");
return settings -> settings.customTrident(new CustomTrident(customTridentItemId, displayType, translation, rotationLefts));
}));
}
private static void registerFactory(String id, ItemSettings.Modifier.Factory factory) {

View File

@@ -197,4 +197,16 @@ public class MCUtils {
public static float unpackDegrees(byte degrees) {
return (float)(degrees * 360) / 256.0F;
}
public static int clamp(int value, int min, int max) {
return Math.min(Math.max(value, min), max);
}
public static float clamp(float value, float min, float max) {
return value < min ? min : Math.min(value, max);
}
public static double clamp(double value, double min, double max) {
return value < min ? min : Math.min(value, max);
}
}

View File

@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3
snake_yaml_version=2.4
anti_grief_version=0.15
nms_helper_version=0.65.15
nms_helper_version=0.65.17
evalex_version=3.5.0
reactive_streams_version=1.0.4
amazon_awssdk_version=2.31.23