9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 12:29:15 +00:00
This commit is contained in:
XiaoMoMi
2025-06-29 23:32:16 +08:00
parent 997890ca38
commit 862a9d0aea
30 changed files with 241 additions and 368 deletions

View File

@@ -89,11 +89,10 @@ public class BukkitFurniture implements Furniture {
List<Object> minimizedPackets = new ArrayList<>();
List<Collider> colliders = new ArrayList<>();
WorldPosition position = position();
Integer dyedColor = this.extraData.dyedColor().orElse(null);
for (FurnitureElement element : placement.elements()) {
int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet();
fakeEntityIds.add(entityId);
element.initPackets(entityId, position, conjugated, dyedColor, packet -> {
element.initPackets(this, entityId, conjugated, packet -> {
packets.add(packet);
if (this.minimized) minimizedPackets.add(packet);
});

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.entity.furniture;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
@@ -8,14 +9,19 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityType
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.Furniture;
import net.momirealms.craftengine.core.entity.furniture.FurnitureElement;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.GsonHelper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.WorldPosition;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@@ -45,16 +51,24 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
}
@Override
public void initPackets(int entityId, @NotNull WorldPosition position, @NotNull Quaternionf conjugated, Integer dyedColor, Consumer<Object> packets) {
public void initPackets(Furniture furniture, int entityId, @NotNull Quaternionf conjugated, Consumer<Object> packets) {
WorldPosition position = furniture.position();
Vector3f offset = conjugated.transform(new Vector3f(position()));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId, UUID.randomUUID(), position.x() + offset.x, position.y() + offset.y, position.z() - offset.z, 0, position.xRot(),
MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0
));
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues(dyedColor)));
if (applyDyedColor()) {
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues(
furniture.extraData().dyedColor().orElse(null),
furniture.extraData().fireworkExplosionColors().orElse(null)
)));
} else {
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, getCachedValues(null, null)));
}
}
private synchronized List<Object> getCachedValues(Integer color) {
private synchronized List<Object> getCachedValues(@Nullable Integer color, int @Nullable [] colors) {
List<Object> cachedValues = new ArrayList<>(this.commonValues);
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(item(), null);
if (item == null) {
@@ -64,6 +78,15 @@ public class BukkitFurnitureElement extends AbstractFurnitureElement {
if (color != null) {
item.dyedColor(color);
}
if (colors != null) {
item.fireworkExplosion(new FireworkExplosion(
FireworkExplosion.Shape.SMALL_BALL,
new IntArrayList(colors),
new IntArrayList(),
false,
false
));
}
}
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), cachedValues);
return cachedValues;

View File

@@ -29,6 +29,7 @@ public class ComponentTypes {
public static final Object PROFILE = getComponentType(ComponentKeys.PROFILE);
public static final Object DYED_COLOR = getComponentType(ComponentKeys.DYED_COLOR);
public static final Object DEATH_PROTECTION = getComponentType(ComponentKeys.DEATH_PROTECTION);
public static final Object FIREWORK_EXPLOSION = getComponentType(ComponentKeys.FIREWORK_EXPLOSION);
private ComponentTypes() {}

View File

@@ -135,6 +135,7 @@ public class FurnitureItemBehavior extends ItemBehavior {
.item(item.copyWithCount(1))
.anchorType(anchorType)
.dyedColor(item.dyedColor().orElse(null))
.fireworkExplosionColors(item.fireworkExplosion().map(explosion -> explosion.colors().toIntArray()).orElse(null))
.build(), false);
FurniturePlaceEvent placeEvent = new FurniturePlaceEvent(bukkitPlayer, bukkitFurniture, furnitureLocation, context.getHand());

View File

@@ -5,7 +5,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect
import net.momirealms.craftengine.bukkit.util.ItemTags;
import net.momirealms.craftengine.core.item.ItemFactory;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
import net.momirealms.craftengine.core.item.setting.EquipmentData;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;

View File

@@ -1,6 +1,7 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
@@ -9,18 +10,17 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInReg
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
import net.momirealms.craftengine.bukkit.util.EnchantmentUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Trim;
import net.momirealms.craftengine.core.item.data.Enchantment;
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
import net.momirealms.craftengine.core.item.data.Trim;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemWrapper> {
@@ -479,6 +479,41 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
return Optional.of(new Trim(trimMap.get("pattern"), trimMap.get("material")));
}
@SuppressWarnings("unchecked")
@Override
protected Optional<FireworkExplosion> fireworkExplosion(ComponentItemWrapper item) {
Optional<Object> optionalExplosion = item.getJavaComponent(ComponentTypes.FIREWORK_EXPLOSION);
if (optionalExplosion.isEmpty()) return Optional.empty();
Map<String, Object> explosions = MiscUtils.castToMap(optionalExplosion.get(), false);
FireworkExplosion.Shape shape = Optional.ofNullable(FireworkExplosion.Shape.byName((String) explosions.get("shape"))).orElse(FireworkExplosion.Shape.SMALL_BALL);
boolean hasTrail = (boolean) explosions.getOrDefault("has_trail", false);
boolean hasTwinkler = (boolean) explosions.getOrDefault("has_twinkle", false);
List<Integer> colors = (List<Integer>) Optional.ofNullable(explosions.get("colors")).orElse(new IntArrayList());
List<Integer> fadeColors = (List<Integer>) Optional.ofNullable(explosions.get("fade_colors")).orElse(new IntArrayList());
return Optional.of(new FireworkExplosion(
shape,
new IntArrayList(colors),
new IntArrayList(fadeColors),
hasTrail,
hasTwinkler
));
}
@Override
protected void fireworkExplosion(ComponentItemWrapper item, FireworkExplosion explosion) {
if (explosion == null) {
item.resetComponent(ComponentTypes.FIREWORK_EXPLOSION);
} else {
item.setJavaComponent(ComponentTypes.FIREWORK_EXPLOSION, Map.of(
"shape", explosion.shape().getName(),
"has_trail", explosion.hasTrail(),
"has_twinkle", explosion.hasTwinkle(),
"colors", explosion.colors(),
"fade_colors", explosion.fadeColors()
));
}
}
@Override
protected ComponentItemWrapper mergeCopy(ComponentItemWrapper item1, ComponentItemWrapper item2) {
Object itemStack1 = item1.getLiteralObject();

View File

@@ -2,7 +2,7 @@ package net.momirealms.craftengine.bukkit.item.factory;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import java.util.Map;

View File

@@ -5,7 +5,7 @@ import com.google.gson.JsonElement;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.GsonHelper;

View File

@@ -1,11 +1,13 @@
package net.momirealms.craftengine.bukkit.item.factory;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.momirealms.craftengine.bukkit.item.LegacyItemWrapper;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Trim;
import net.momirealms.craftengine.core.item.data.Enchantment;
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
import net.momirealms.craftengine.core.item.data.Trim;
import net.momirealms.craftengine.core.item.modifier.IdModifier;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
@@ -260,6 +262,38 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
item.setTag(trim.pattern(), "Trim", "pattern");
}
@Override
protected Optional<FireworkExplosion> fireworkExplosion(LegacyItemWrapper item) {
Map<String, Object> explosionObj = item.getJavaTag("Explosion");
if (explosionObj == null) return Optional.empty();
IntArrayList colors = (IntArrayList) explosionObj.get("Colors");
IntArrayList fadeColors = (IntArrayList) explosionObj.get("FadeColors");
return Optional.of(
new FireworkExplosion(
FireworkExplosion.Shape.byId((Integer) explosionObj.getOrDefault("Type", 0)),
colors == null ? new IntArrayList() : new IntArrayList(colors),
fadeColors == null ? new IntArrayList() : new IntArrayList(fadeColors),
(boolean) explosionObj.getOrDefault("Trail", false),
(boolean) explosionObj.getOrDefault("Flicker", false)
)
);
}
@Override
protected void fireworkExplosion(LegacyItemWrapper item, FireworkExplosion explosion) {
if (explosion == null) {
item.remove("Explosion");
} else {
item.setTag(Map.of(
"Type", explosion.shape().id(),
"Colors", explosion.colors(),
"FadeColors", explosion.fadeColors(),
"Trail", explosion.hasTrail(),
"Flicker", explosion.hasTwinkle()
), "Explosion");
}
}
@Override
protected Optional<Trim> trim(LegacyItemWrapper item) {
String material = item.getJavaTag("Trim", "material");

View File

@@ -758,7 +758,7 @@ public class RecipeEventListener implements Listener {
int newItemDamage = Math.max(0, newItem.maxDamage() - remainingDurability);
newItem.damage(newItemDamage);
inventory.setResult(newItem.getItem());
} else if (CoreReflections.clazz$ArmorDyeRecipe.isInstance(mcRecipe)) {
} else if (CoreReflections.clazz$ArmorDyeRecipe.isInstance(mcRecipe) || CoreReflections.clazz$FireworkStarFadeRecipe.isInstance(mcRecipe)) {
ItemStack[] itemStacks = inventory.getMatrix();
for (ItemStack itemStack : itemStacks) {
if (itemStack == null) continue;

View File

@@ -2257,6 +2257,27 @@ public final class CoreReflections {
)
);
public static final Class<?> clazz$FireworkRocketRecipe = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.item.crafting.RecipeFireworks",
"world.item.crafting.FireworkRocketRecipe"
)
);
public static final Class<?> clazz$FireworkStarRecipe = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.item.crafting.RecipeFireworksStar",
"world.item.crafting.FireworkStarRecipe"
)
);
public static final Class<?> clazz$FireworkStarFadeRecipe = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.item.crafting.RecipeFireworksFade",
"world.item.crafting.FireworkStarFadeRecipe"
)
);
public static final Class<?> clazz$AnvilMenu = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.inventory.ContainerAnvil",