#1279: Back Particle by a minecraft registry
This commit is contained in:
parent
f4d977e794
commit
67a52a6485
@ -1,11 +1,10 @@
|
|||||||
package org.bukkit.craftbukkit;
|
package org.bukkit.craftbukkit;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.BiMap;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.minecraft.core.BlockPosition;
|
import java.util.function.BiFunction;
|
||||||
|
import net.minecraft.core.IRegistry;
|
||||||
import net.minecraft.core.particles.DustColorTransitionOptions;
|
import net.minecraft.core.particles.DustColorTransitionOptions;
|
||||||
import net.minecraft.core.particles.ParticleParam;
|
import net.minecraft.core.particles.ParticleParam;
|
||||||
import net.minecraft.core.particles.ParticleParamBlock;
|
import net.minecraft.core.particles.ParticleParamBlock;
|
||||||
@ -15,15 +14,17 @@ import net.minecraft.core.particles.ParticleType;
|
|||||||
import net.minecraft.core.particles.SculkChargeParticleOptions;
|
import net.minecraft.core.particles.SculkChargeParticleOptions;
|
||||||
import net.minecraft.core.particles.ShriekParticleOption;
|
import net.minecraft.core.particles.ShriekParticleOption;
|
||||||
import net.minecraft.core.particles.VibrationParticleOption;
|
import net.minecraft.core.particles.VibrationParticleOption;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.MinecraftKey;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.gameevent.BlockPositionSource;
|
import net.minecraft.world.level.gameevent.BlockPositionSource;
|
||||||
import net.minecraft.world.level.gameevent.EntityPositionSource;
|
import net.minecraft.world.level.gameevent.EntityPositionSource;
|
||||||
import net.minecraft.world.level.gameevent.PositionSource;
|
import net.minecraft.world.level.gameevent.PositionSource;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.Keyed;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Registry;
|
||||||
import org.bukkit.Vibration;
|
import org.bukkit.Vibration;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
@ -31,205 +32,184 @@ import org.bukkit.craftbukkit.entity.CraftEntity;
|
|||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
|
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.material.MaterialData;
|
import org.bukkit.material.MaterialData;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
public enum CraftParticle {
|
public abstract class CraftParticle<D> implements Keyed {
|
||||||
|
|
||||||
EXPLOSION_NORMAL("poof"),
|
private static final Registry<CraftParticle<?>> CRAFT_PARTICLE_REGISTRY = new CraftParticleRegistry(CraftRegistry.getMinecraftRegistry(Registries.PARTICLE_TYPE));
|
||||||
EXPLOSION_LARGE("explosion"),
|
|
||||||
EXPLOSION_HUGE("explosion_emitter"),
|
|
||||||
FIREWORKS_SPARK("firework"),
|
|
||||||
WATER_BUBBLE("bubble"),
|
|
||||||
WATER_SPLASH("splash"),
|
|
||||||
WATER_WAKE("fishing"),
|
|
||||||
SUSPENDED("underwater"),
|
|
||||||
SUSPENDED_DEPTH("underwater"),
|
|
||||||
CRIT("crit"),
|
|
||||||
CRIT_MAGIC("enchanted_hit"),
|
|
||||||
SMOKE_NORMAL("smoke"),
|
|
||||||
SMOKE_LARGE("large_smoke"),
|
|
||||||
SPELL("effect"),
|
|
||||||
SPELL_INSTANT("instant_effect"),
|
|
||||||
SPELL_MOB("entity_effect"),
|
|
||||||
SPELL_MOB_AMBIENT("ambient_entity_effect"),
|
|
||||||
SPELL_WITCH("witch"),
|
|
||||||
DRIP_WATER("dripping_water"),
|
|
||||||
DRIP_LAVA("dripping_lava"),
|
|
||||||
VILLAGER_ANGRY("angry_villager"),
|
|
||||||
VILLAGER_HAPPY("happy_villager"),
|
|
||||||
TOWN_AURA("mycelium"),
|
|
||||||
NOTE("note"),
|
|
||||||
PORTAL("portal"),
|
|
||||||
ENCHANTMENT_TABLE("enchant"),
|
|
||||||
FLAME("flame"),
|
|
||||||
LAVA("lava"),
|
|
||||||
CLOUD("cloud"),
|
|
||||||
REDSTONE("dust"),
|
|
||||||
SNOWBALL("item_snowball"),
|
|
||||||
SNOW_SHOVEL("item_snowball"),
|
|
||||||
SLIME("item_slime"),
|
|
||||||
HEART("heart"),
|
|
||||||
ITEM_CRACK("item"),
|
|
||||||
BLOCK_CRACK("block"),
|
|
||||||
BLOCK_DUST("block"),
|
|
||||||
WATER_DROP("rain"),
|
|
||||||
MOB_APPEARANCE("elder_guardian"),
|
|
||||||
DRAGON_BREATH("dragon_breath"),
|
|
||||||
END_ROD("end_rod"),
|
|
||||||
DAMAGE_INDICATOR("damage_indicator"),
|
|
||||||
SWEEP_ATTACK("sweep_attack"),
|
|
||||||
FALLING_DUST("falling_dust"),
|
|
||||||
TOTEM("totem_of_undying"),
|
|
||||||
SPIT("spit"),
|
|
||||||
SQUID_INK("squid_ink"),
|
|
||||||
BUBBLE_POP("bubble_pop"),
|
|
||||||
CURRENT_DOWN("current_down"),
|
|
||||||
BUBBLE_COLUMN_UP("bubble_column_up"),
|
|
||||||
NAUTILUS("nautilus"),
|
|
||||||
DOLPHIN("dolphin"),
|
|
||||||
SNEEZE("sneeze"),
|
|
||||||
CAMPFIRE_COSY_SMOKE("campfire_cosy_smoke"),
|
|
||||||
CAMPFIRE_SIGNAL_SMOKE("campfire_signal_smoke"),
|
|
||||||
COMPOSTER("composter"),
|
|
||||||
FLASH("flash"),
|
|
||||||
FALLING_LAVA("falling_lava"),
|
|
||||||
LANDING_LAVA("landing_lava"),
|
|
||||||
FALLING_WATER("falling_water"),
|
|
||||||
DRIPPING_HONEY("dripping_honey"),
|
|
||||||
FALLING_HONEY("falling_honey"),
|
|
||||||
LANDING_HONEY("landing_honey"),
|
|
||||||
FALLING_NECTAR("falling_nectar"),
|
|
||||||
SOUL_FIRE_FLAME("soul_fire_flame"),
|
|
||||||
ASH("ash"),
|
|
||||||
CRIMSON_SPORE("crimson_spore"),
|
|
||||||
WARPED_SPORE("warped_spore"),
|
|
||||||
SOUL("soul"),
|
|
||||||
DRIPPING_OBSIDIAN_TEAR("dripping_obsidian_tear"),
|
|
||||||
FALLING_OBSIDIAN_TEAR("falling_obsidian_tear"),
|
|
||||||
LANDING_OBSIDIAN_TEAR("landing_obsidian_tear"),
|
|
||||||
REVERSE_PORTAL("reverse_portal"),
|
|
||||||
WHITE_ASH("white_ash"),
|
|
||||||
DUST_COLOR_TRANSITION("dust_color_transition"),
|
|
||||||
VIBRATION("vibration"),
|
|
||||||
FALLING_SPORE_BLOSSOM("falling_spore_blossom"),
|
|
||||||
SPORE_BLOSSOM_AIR("spore_blossom_air"),
|
|
||||||
SMALL_FLAME("small_flame"),
|
|
||||||
SNOWFLAKE("snowflake"),
|
|
||||||
DRIPPING_DRIPSTONE_LAVA("dripping_dripstone_lava"),
|
|
||||||
FALLING_DRIPSTONE_LAVA("falling_dripstone_lava"),
|
|
||||||
DRIPPING_DRIPSTONE_WATER("dripping_dripstone_water"),
|
|
||||||
FALLING_DRIPSTONE_WATER("falling_dripstone_water"),
|
|
||||||
GLOW_SQUID_INK("glow_squid_ink"),
|
|
||||||
GLOW("glow"),
|
|
||||||
WAX_ON("wax_on"),
|
|
||||||
WAX_OFF("wax_off"),
|
|
||||||
ELECTRIC_SPARK("electric_spark"),
|
|
||||||
SCRAPE("scrape"),
|
|
||||||
BLOCK_MARKER("block_marker"),
|
|
||||||
SONIC_BOOM("sonic_boom"),
|
|
||||||
SCULK_SOUL("sculk_soul"),
|
|
||||||
SCULK_CHARGE("sculk_charge"),
|
|
||||||
SCULK_CHARGE_POP("sculk_charge_pop"),
|
|
||||||
SHRIEK("shriek"),
|
|
||||||
CHERRY_LEAVES("cherry_leaves"),
|
|
||||||
EGG_CRACK("egg_crack"),
|
|
||||||
// ----- Legacy Separator -----
|
|
||||||
LEGACY_BLOCK_CRACK("block"),
|
|
||||||
LEGACY_BLOCK_DUST("block"),
|
|
||||||
LEGACY_FALLING_DUST("falling_dust");
|
|
||||||
private final MinecraftKey minecraftKey;
|
|
||||||
private final Particle bukkit;
|
|
||||||
private static final BiMap<Particle, MinecraftKey> particles;
|
|
||||||
private static final Map<Particle, Particle> aliases;
|
|
||||||
|
|
||||||
static {
|
|
||||||
particles = HashBiMap.create();
|
|
||||||
aliases = new HashMap<>();
|
|
||||||
|
|
||||||
for (CraftParticle particle : CraftParticle.values()) {
|
|
||||||
if (particles.containsValue(particle.minecraftKey)) {
|
|
||||||
aliases.put(particle.bukkit, particles.inverse().get(particle.minecraftKey));
|
|
||||||
} else {
|
|
||||||
particles.put(particle.bukkit, particle.minecraftKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CraftParticle(String minecraftKey) {
|
|
||||||
this.minecraftKey = new MinecraftKey(minecraftKey);
|
|
||||||
|
|
||||||
this.bukkit = Particle.valueOf(this.name());
|
|
||||||
Preconditions.checkState(bukkit != null, "Bukkit particle %s does not exist", this.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ParticleParam toNMS(Particle bukkit) {
|
|
||||||
return toNMS(bukkit, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> ParticleParam toNMS(Particle particle, T obj) {
|
|
||||||
Particle canonical = particle;
|
|
||||||
if (aliases.containsKey(particle)) {
|
|
||||||
canonical = aliases.get(particle);
|
|
||||||
}
|
|
||||||
|
|
||||||
net.minecraft.core.particles.Particle nms = BuiltInRegistries.PARTICLE_TYPE.get(particles.get(canonical));
|
|
||||||
Preconditions.checkArgument(nms != null, "No NMS particle %s", particle);
|
|
||||||
|
|
||||||
if (particle.getDataType().equals(Void.class)) {
|
|
||||||
return (ParticleType) nms;
|
|
||||||
}
|
|
||||||
Preconditions.checkArgument(obj != null, "Particle %s requires data, null provided", particle);
|
|
||||||
if (particle.getDataType().equals(ItemStack.class)) {
|
|
||||||
ItemStack itemStack = (ItemStack) obj;
|
|
||||||
return new ParticleParamItem((net.minecraft.core.particles.Particle<ParticleParamItem>) nms, CraftItemStack.asNMSCopy(itemStack));
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == MaterialData.class) {
|
|
||||||
MaterialData data = (MaterialData) obj;
|
|
||||||
return new ParticleParamBlock((net.minecraft.core.particles.Particle<ParticleParamBlock>) nms, CraftMagicNumbers.getBlock(data));
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == BlockData.class) {
|
|
||||||
BlockData data = (BlockData) obj;
|
|
||||||
return new ParticleParamBlock((net.minecraft.core.particles.Particle<ParticleParamBlock>) nms, ((CraftBlockData) data).getState());
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == Particle.DustOptions.class) {
|
|
||||||
Particle.DustOptions data = (Particle.DustOptions) obj;
|
|
||||||
Color color = data.getColor();
|
|
||||||
return new ParticleParamRedstone(new Vector3f(color.getRed() / 255.0f, color.getGreen() / 255.0f, color.getBlue() / 255.0f), data.getSize());
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == Particle.DustTransition.class) {
|
|
||||||
Particle.DustTransition data = (Particle.DustTransition) obj;
|
|
||||||
Color from = data.getColor();
|
|
||||||
Color to = data.getToColor();
|
|
||||||
return new DustColorTransitionOptions(new Vector3f(from.getRed() / 255.0f, from.getGreen() / 255.0f, from.getBlue() / 255.0f), new Vector3f(to.getRed() / 255.0f, to.getGreen() / 255.0f, to.getBlue() / 255.0f), data.getSize());
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == Vibration.class) {
|
|
||||||
Vibration vibration = (Vibration) obj;
|
|
||||||
|
|
||||||
PositionSource source;
|
|
||||||
if (vibration.getDestination() instanceof Vibration.Destination.BlockDestination) {
|
|
||||||
Location destination = ((Vibration.Destination.BlockDestination) vibration.getDestination()).getLocation();
|
|
||||||
source = new BlockPositionSource(CraftLocation.toBlockPosition(destination));
|
|
||||||
} else if (vibration.getDestination() instanceof Vibration.Destination.EntityDestination) {
|
|
||||||
Entity destination = ((CraftEntity) ((Vibration.Destination.EntityDestination) vibration.getDestination()).getEntity()).getHandle();
|
|
||||||
source = new EntityPositionSource(destination, destination.getEyeHeight());
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown vibration destination " + vibration.getDestination());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new VibrationParticleOption(source, vibration.getArrivalTime());
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == Float.class) {
|
|
||||||
return new SculkChargeParticleOptions((Float) obj);
|
|
||||||
}
|
|
||||||
if (particle.getDataType() == Integer.class) {
|
|
||||||
return new ShriekParticleOption((Integer) obj);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException(particle.getDataType().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Particle minecraftToBukkit(net.minecraft.core.particles.Particle<?> minecraft) {
|
public static Particle minecraftToBukkit(net.minecraft.core.particles.Particle<?> minecraft) {
|
||||||
return particles.inverse().get(BuiltInRegistries.PARTICLE_TYPE.getKey(minecraft));
|
Preconditions.checkArgument(minecraft != null);
|
||||||
|
|
||||||
|
IRegistry<net.minecraft.core.particles.Particle<?>> registry = CraftRegistry.getMinecraftRegistry(Registries.PARTICLE_TYPE);
|
||||||
|
Particle bukkit = Registry.PARTICLE_TYPE.get(CraftNamespacedKey.fromMinecraft(registry.getResourceKey(minecraft).orElseThrow().location()));
|
||||||
|
|
||||||
|
Preconditions.checkArgument(bukkit != null);
|
||||||
|
|
||||||
|
return bukkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static net.minecraft.core.particles.Particle<?> bukkitToMinecraft(Particle bukkit) {
|
||||||
|
Preconditions.checkArgument(bukkit != null);
|
||||||
|
|
||||||
|
return CraftRegistry.getMinecraftRegistry(Registries.PARTICLE_TYPE)
|
||||||
|
.getOptional(CraftNamespacedKey.toMinecraft(bukkit.getKey())).orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <D> ParticleParam createParticleParam(Particle particle, D data) {
|
||||||
|
Preconditions.checkArgument(particle != null);
|
||||||
|
|
||||||
|
CraftParticle<D> craftParticle = (CraftParticle<D>) CRAFT_PARTICLE_REGISTRY.get(particle.getKey());
|
||||||
|
|
||||||
|
Preconditions.checkArgument(craftParticle != null);
|
||||||
|
|
||||||
|
return craftParticle.createParticleParam(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T convertLegacy(T object) {
|
||||||
|
if (object instanceof MaterialData mat) {
|
||||||
|
return (T) CraftBlockData.fromData(CraftMagicNumbers.getBlock(mat));
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Particle convertLegacy(Particle particle) {
|
||||||
|
return switch (particle) {
|
||||||
|
case LEGACY_BLOCK_DUST -> Particle.BLOCK_DUST;
|
||||||
|
case LEGACY_FALLING_DUST -> Particle.FALLING_DUST;
|
||||||
|
case LEGACY_BLOCK_CRACK -> Particle.BLOCK_CRACK;
|
||||||
|
default -> particle;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private final NamespacedKey key;
|
||||||
|
private final net.minecraft.core.particles.Particle<?> particle;
|
||||||
|
private final Class<D> clazz;
|
||||||
|
|
||||||
|
public CraftParticle(NamespacedKey key, net.minecraft.core.particles.Particle<?> particle, Class<D> clazz) {
|
||||||
|
this.key = key;
|
||||||
|
this.particle = particle;
|
||||||
|
this.clazz = clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public net.minecraft.core.particles.Particle<?> getHandle() {
|
||||||
|
return particle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ParticleParam createParticleParam(D data);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CraftParticleRegistry extends CraftRegistry<CraftParticle<?>, net.minecraft.core.particles.Particle<?>> {
|
||||||
|
|
||||||
|
private static final Map<NamespacedKey, BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>>> PARTICLE_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
private static final BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> VOID_FUNCTION = (name, particle) -> new CraftParticle<>(name, particle, Void.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(Void data) {
|
||||||
|
return (ParticleType) getHandle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static {
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> dustOptionsFunction = (name, particle) -> new CraftParticle<>(name, particle, Particle.DustOptions.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(Particle.DustOptions data) {
|
||||||
|
Color color = data.getColor();
|
||||||
|
return new ParticleParamRedstone(new Vector3f(color.getRed() / 255.0f, color.getGreen() / 255.0f, color.getBlue() / 255.0f), data.getSize());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> itemStackFunction = (name, particle) -> new CraftParticle<>(name, particle, ItemStack.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(ItemStack data) {
|
||||||
|
return new ParticleParamItem((net.minecraft.core.particles.Particle<ParticleParamItem>) getHandle(), CraftItemStack.asNMSCopy(data));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> blockDataFunction = (name, particle) -> new CraftParticle<>(name, particle, BlockData.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(BlockData data) {
|
||||||
|
return new ParticleParamBlock((net.minecraft.core.particles.Particle<ParticleParamBlock>) getHandle(), ((CraftBlockData) data).getState());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> dustTransitionFunction = (name, particle) -> new CraftParticle<>(name, particle, Particle.DustTransition.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(Particle.DustTransition data) {
|
||||||
|
Color from = data.getColor();
|
||||||
|
Color to = data.getToColor();
|
||||||
|
return new DustColorTransitionOptions(new Vector3f(from.getRed() / 255.0f, from.getGreen() / 255.0f, from.getBlue() / 255.0f), new Vector3f(to.getRed() / 255.0f, to.getGreen() / 255.0f, to.getBlue() / 255.0f), data.getSize());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> vibrationFunction = (name, particle) -> new CraftParticle<>(name, particle, Vibration.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(Vibration data) {
|
||||||
|
PositionSource source;
|
||||||
|
if (data.getDestination() instanceof Vibration.Destination.BlockDestination) {
|
||||||
|
Location destination = ((Vibration.Destination.BlockDestination) data.getDestination()).getLocation();
|
||||||
|
source = new BlockPositionSource(CraftLocation.toBlockPosition(destination));
|
||||||
|
} else if (data.getDestination() instanceof Vibration.Destination.EntityDestination) {
|
||||||
|
Entity destination = ((CraftEntity) ((Vibration.Destination.EntityDestination) data.getDestination()).getEntity()).getHandle();
|
||||||
|
source = new EntityPositionSource(destination, destination.getEyeHeight());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unknown vibration destination " + data.getDestination());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VibrationParticleOption(source, data.getArrivalTime());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> floatFunction = (name, particle) -> new CraftParticle<>(name, particle, Float.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(Float data) {
|
||||||
|
return new SculkChargeParticleOptions(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> integerFunction = (name, particle) -> new CraftParticle<>(name, particle, Integer.class) {
|
||||||
|
@Override
|
||||||
|
public ParticleParam createParticleParam(Integer data) {
|
||||||
|
return new ShriekParticleOption(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
add("dust", dustOptionsFunction);
|
||||||
|
add("item", itemStackFunction);
|
||||||
|
add("block", blockDataFunction);
|
||||||
|
add("falling_dust", blockDataFunction);
|
||||||
|
add("dust_color_transition", dustTransitionFunction);
|
||||||
|
add("vibration", vibrationFunction);
|
||||||
|
add("sculk_charge", floatFunction);
|
||||||
|
add("shriek", integerFunction);
|
||||||
|
add("block_marker", blockDataFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void add(String name, BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> function) {
|
||||||
|
PARTICLE_MAP.put(NamespacedKey.fromString(name), function);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CraftParticleRegistry(IRegistry<net.minecraft.core.particles.Particle<?>> minecraftRegistry) {
|
||||||
|
super(CraftParticle.class, minecraftRegistry, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftParticle<?> createBukkit(NamespacedKey namespacedKey, net.minecraft.core.particles.Particle<?> particle) {
|
||||||
|
if (particle == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiFunction<NamespacedKey, net.minecraft.core.particles.Particle<?>, CraftParticle<?>> function = PARTICLE_MAP.getOrDefault(namespacedKey, VOID_FUNCTION);
|
||||||
|
|
||||||
|
return function.apply(namespacedKey, particle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,13 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Class<B> bukkitClass;
|
private final Class<? super B> bukkitClass;
|
||||||
private final Map<NamespacedKey, B> cache = new HashMap<>();
|
private final Map<NamespacedKey, B> cache = new HashMap<>();
|
||||||
private final IRegistry<M> minecraftRegistry;
|
private final IRegistry<M> minecraftRegistry;
|
||||||
private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
|
private final BiFunction<NamespacedKey, M, B> minecraftToBukkit;
|
||||||
private boolean init;
|
private boolean init;
|
||||||
|
|
||||||
public CraftRegistry(Class<B> bukkitClass, IRegistry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
|
public CraftRegistry(Class<? super B> bukkitClass, IRegistry<M> minecraftRegistry, BiFunction<NamespacedKey, M, B> minecraftToBukkit) {
|
||||||
this.bukkitClass = bukkitClass;
|
this.bukkitClass = bukkitClass;
|
||||||
this.minecraftRegistry = minecraftRegistry;
|
this.minecraftRegistry = minecraftRegistry;
|
||||||
this.minecraftToBukkit = minecraftToBukkit;
|
this.minecraftToBukkit = minecraftToBukkit;
|
||||||
|
@ -1788,12 +1788,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
|
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
|
||||||
|
particle = CraftParticle.convertLegacy(particle);
|
||||||
|
data = CraftParticle.convertLegacy(data);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
||||||
}
|
}
|
||||||
getHandle().sendParticles(
|
getHandle().sendParticles(
|
||||||
null, // Sender
|
null, // Sender
|
||||||
CraftParticle.toNMS(particle, data), // Particle
|
CraftParticle.createParticleParam(particle, data), // Particle
|
||||||
x, y, z, // Position
|
x, y, z, // Position
|
||||||
count, // Count
|
count, // Count
|
||||||
offsetX, offsetY, offsetZ, // Random offset
|
offsetX, offsetY, offsetZ, // Random offset
|
||||||
|
@ -121,7 +121,12 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void setParticle(Particle particle, T data) {
|
public <T> void setParticle(Particle particle, T data) {
|
||||||
getHandle().setParticle(CraftParticle.toNMS(particle, data));
|
particle = CraftParticle.convertLegacy(particle);
|
||||||
|
data = CraftParticle.convertLegacy(data);
|
||||||
|
if (data != null) {
|
||||||
|
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
||||||
|
}
|
||||||
|
getHandle().setParticle(CraftParticle.createParticleParam(particle, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2080,10 +2080,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) {
|
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) {
|
||||||
|
particle = CraftParticle.convertLegacy(particle);
|
||||||
|
data = CraftParticle.convertLegacy(data);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
||||||
}
|
}
|
||||||
PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(CraftParticle.toNMS(particle, data), true, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count);
|
PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(CraftParticle.createParticleParam(particle, data), true, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count);
|
||||||
getHandle().connection.send(packetplayoutworldparticles);
|
getHandle().connection.send(packetplayoutworldparticles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,280 @@
|
|||||||
package org.bukkit;
|
package org.bukkit;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import com.mojang.serialization.DataResult;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import net.minecraft.core.particles.DustColorTransitionOptions;
|
||||||
|
import net.minecraft.core.particles.ParticleParam;
|
||||||
|
import net.minecraft.core.particles.ParticleParamBlock;
|
||||||
|
import net.minecraft.core.particles.ParticleParamItem;
|
||||||
|
import net.minecraft.core.particles.ParticleParamRedstone;
|
||||||
|
import net.minecraft.core.particles.ParticleType;
|
||||||
|
import net.minecraft.core.particles.SculkChargeParticleOptions;
|
||||||
|
import net.minecraft.core.particles.ShriekParticleOption;
|
||||||
|
import net.minecraft.core.particles.VibrationParticleOption;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.nbt.DynamicOpsNBT;
|
||||||
|
import net.minecraft.nbt.NBTBase;
|
||||||
|
import net.minecraft.resources.MinecraftKey;
|
||||||
|
import net.minecraft.world.phys.Vec3D;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.craftbukkit.CraftParticle;
|
import org.bukkit.craftbukkit.CraftParticle;
|
||||||
|
import org.bukkit.craftbukkit.CraftRegistry;
|
||||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.material.MaterialData;
|
|
||||||
import org.bukkit.support.AbstractTestingBase;
|
import org.bukkit.support.AbstractTestingBase;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.joml.Vector3f;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
public class ParticleTest extends AbstractTestingBase {
|
public class ParticleTest extends AbstractTestingBase {
|
||||||
|
|
||||||
@Test
|
public static Stream<Arguments> data() {
|
||||||
public void verifyMapping() {
|
return CraftRegistry.getMinecraftRegistry(Registries.PARTICLE_TYPE).keySet().stream().map(Arguments::of);
|
||||||
for (Particle bukkit : Particle.values()) {
|
}
|
||||||
Object data = null;
|
|
||||||
if (bukkit.getDataType().equals(ItemStack.class)) {
|
|
||||||
data = new ItemStack(Material.STONE);
|
|
||||||
} else if (bukkit.getDataType() == MaterialData.class) {
|
|
||||||
data = new MaterialData(Material.LEGACY_STONE);
|
|
||||||
} else if (bukkit.getDataType() == Particle.DustOptions.class) {
|
|
||||||
data = new Particle.DustOptions(Color.BLACK, 0);
|
|
||||||
} else if (bukkit.getDataType() == Particle.DustTransition.class) {
|
|
||||||
data = new Particle.DustTransition(Color.BLACK, Color.WHITE, 0);
|
|
||||||
} else if (bukkit.getDataType() == Vibration.class) {
|
|
||||||
data = new Vibration(new Location(null, 0, 0, 0), new Vibration.Destination.BlockDestination(new Location(null, 0, 0, 0)), 0);
|
|
||||||
} else if (bukkit.getDataType() == BlockData.class) {
|
|
||||||
data = CraftBlockData.newData(Material.STONE, "");
|
|
||||||
} else if (bukkit.getDataType() == Float.class) {
|
|
||||||
data = 1.0F;
|
|
||||||
} else if (bukkit.getDataType() == Integer.class) {
|
|
||||||
data = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assertNotNull(CraftParticle.toNMS(bukkit, data), "Missing Bukkit->NMS particle mapping for " + bukkit);
|
@ParameterizedTest
|
||||||
|
@MethodSource("data")
|
||||||
|
public void testBukkitValuesPresent(MinecraftKey minecraft) {
|
||||||
|
// TODO: 10/19/23 Remove with enum PR, it is then no longer needed, since the enum PR has a extra test for this
|
||||||
|
assertNotNull(Registry.PARTICLE_TYPE.get(CraftNamespacedKey.fromMinecraft(minecraft)), String.format("""
|
||||||
|
No bukkit particle found for minecraft particle %s.
|
||||||
|
Please add the particle to bukkit.
|
||||||
|
""", minecraft));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnumSource(Particle.class)
|
||||||
|
public void testMinecraftValuesPresent(Particle bukkit) {
|
||||||
|
// TODO: 10/19/23 Remove with enum PR, it is then no longer needed, since the enum PR has a extra test for this
|
||||||
|
bukkit = CraftParticle.convertLegacy(bukkit);
|
||||||
|
Particle finalBukkit = bukkit;
|
||||||
|
assertDoesNotThrow(() -> CraftParticle.bukkitToMinecraft(finalBukkit), String.format("""
|
||||||
|
No minecraft particle found for bukkit particle %s.
|
||||||
|
Please map the bukkit particle to a minecraft particle.
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnumSource(Particle.class)
|
||||||
|
public void testRightParticleParamCreation(Particle bukkit) {
|
||||||
|
bukkit = CraftParticle.convertLegacy(bukkit);
|
||||||
|
net.minecraft.core.particles.Particle<?> minecraft = CraftParticle.bukkitToMinecraft(bukkit);
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(Void.class)) {
|
||||||
|
testEmptyData(bukkit, minecraft);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
for (net.minecraft.core.particles.Particle nms : BuiltInRegistries.PARTICLE_TYPE) {
|
|
||||||
assertNotNull(CraftParticle.minecraftToBukkit(nms), "Missing NMS->Bukkit particle mapping for " + BuiltInRegistries.PARTICLE_TYPE.getKey(nms));
|
if (bukkit.getDataType().equals(Particle.DustOptions.class)) {
|
||||||
|
testDustOption(bukkit, minecraft);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(ItemStack.class)) {
|
||||||
|
testItemStack(bukkit, minecraft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(BlockData.class)) {
|
||||||
|
testBlockData(bukkit, minecraft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(Particle.DustTransition.class)) {
|
||||||
|
testDustTransition(bukkit, minecraft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(Vibration.class)) {
|
||||||
|
testVibration(bukkit, minecraft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(Float.class)) {
|
||||||
|
testFloat(bukkit, minecraft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bukkit.getDataType().equals(Integer.class)) {
|
||||||
|
testInteger(bukkit, minecraft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail(String.format("""
|
||||||
|
No test found for particle %s.
|
||||||
|
Please add a test case for it here.
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testEmptyData(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
createAndTest(bukkit, minecraft, null, ParticleType.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testDustOption(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
Particle.DustOptions dustOptions = new Particle.DustOptions(Color.fromRGB(236, 28, 36), 0.1205f);
|
||||||
|
ParticleParamRedstone param = createAndTest(bukkit, minecraft, dustOptions, ParticleParamRedstone.class);
|
||||||
|
|
||||||
|
assertEquals(0.1205f, param.getScale(), 0.001, String.format("""
|
||||||
|
Dust option scale for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
|
||||||
|
Vector3f expectedColor = new Vector3f(0.92549f, 0.1098f, 0.14117647f);
|
||||||
|
assertTrue(expectedColor.equals(param.getColor(), 0.001f), String.format("""
|
||||||
|
Dust option color for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
Expected: %s.
|
||||||
|
Got: %s.
|
||||||
|
""", bukkit.getKey(), expectedColor, param.getColor())); // Print expected and got since we use assert true
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testItemStack(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
ItemStack itemStack = new ItemStack(Material.STONE);
|
||||||
|
ParticleParamItem param = createAndTest(bukkit, minecraft, itemStack, ParticleParamItem.class);
|
||||||
|
|
||||||
|
assertEquals(itemStack, CraftItemStack.asBukkitCopy(param.getItem()), String.format("""
|
||||||
|
ItemStack for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testBlockData(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
BlockData blockData = Bukkit.createBlockData(Material.STONE);
|
||||||
|
ParticleParamBlock param = createAndTest(bukkit, minecraft, blockData, ParticleParamBlock.class);
|
||||||
|
|
||||||
|
assertEquals(blockData, CraftBlockData.fromData(param.getState()), String.format("""
|
||||||
|
Block data for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testDustTransition(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
Particle.DustTransition dustTransition = new Particle.DustTransition(Color.fromRGB(236, 28, 36), Color.fromRGB(107, 159, 181), 0.1205f);
|
||||||
|
DustColorTransitionOptions param = createAndTest(bukkit, minecraft, dustTransition, DustColorTransitionOptions.class);
|
||||||
|
|
||||||
|
assertEquals(0.1205f, param.getScale(), 0.001, String.format("""
|
||||||
|
Dust transition scale for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
|
||||||
|
Vector3f expectedFrom = new Vector3f(0.92549f, 0.1098f, 0.14117647f);
|
||||||
|
assertTrue(expectedFrom.equals(param.getFromColor(), 0.001f), String.format("""
|
||||||
|
Dust transition from color for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
Expected: %s.
|
||||||
|
Got: %s.
|
||||||
|
""", bukkit.getKey(), expectedFrom, param.getColor())); // Print expected and got since we use assert true
|
||||||
|
|
||||||
|
Vector3f expectedTo = new Vector3f(0.4196f, 0.6235294f, 0.7098f);
|
||||||
|
assertTrue(expectedTo.equals(param.getToColor(), 0.001f), String.format("""
|
||||||
|
Dust transition to color for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
Expected: %s.
|
||||||
|
Got: %s.
|
||||||
|
""", bukkit.getKey(), expectedTo, param.getColor())); // Print expected and got since we use assert true
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testVibration(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
Vibration vibration = new Vibration(new Location(null, 3, 1, 4), new Vibration.Destination.BlockDestination(new Location(null, 1, 5, 9)), 265);
|
||||||
|
VibrationParticleOption param = createAndTest(bukkit, minecraft, vibration, VibrationParticleOption.class);
|
||||||
|
|
||||||
|
assertEquals(265, param.getArrivalInTicks(), String.format("""
|
||||||
|
Vibration ticks for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
|
||||||
|
Optional<Vec3D> pos = param.getDestination().getPosition(null);
|
||||||
|
assertTrue(pos.isPresent(), String.format("""
|
||||||
|
Vibration position for particle %s is not present.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
|
||||||
|
// Add 0.5 since it gets centered to the block
|
||||||
|
assertEquals(new Vec3D(1.5, 5.5, 9.5), pos.get(), String.format("""
|
||||||
|
Vibration position for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testFloat(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
float role = 0.1205f;
|
||||||
|
SculkChargeParticleOptions param = createAndTest(bukkit, minecraft, role, SculkChargeParticleOptions.class);
|
||||||
|
|
||||||
|
assertEquals(role, param.roll(), 0.001, String.format("""
|
||||||
|
Float role for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends ParticleParam> void testInteger(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||||
|
int delay = 1205;
|
||||||
|
ShriekParticleOption param = createAndTest(bukkit, minecraft, delay, ShriekParticleOption.class);
|
||||||
|
|
||||||
|
assertEquals(delay, param.getDelay(), String.format("""
|
||||||
|
Integer delay for particle %s do not match.
|
||||||
|
Did something change in the implementation or minecraft?
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends ParticleParam, T extends ParticleParam> D createAndTest(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft, Object data, Class<D> paramClass) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
T particleParam = (T) assertDoesNotThrow(() -> CraftParticle.createParticleParam(bukkit, data), String.format("""
|
||||||
|
Could not create particle param for particle %s.
|
||||||
|
This can indicated, that the default particle param is used, but the particle requires extra data.
|
||||||
|
Or that something is wrong with the logic which creates the particle param with extra data.
|
||||||
|
Check in CraftParticle if the conversion is still correct.
|
||||||
|
""", bukkit.getKey()));
|
||||||
|
|
||||||
|
DataResult<NBTBase> encoded = assertDoesNotThrow(() -> minecraft.codec().encodeStart(DynamicOpsNBT.INSTANCE, particleParam),
|
||||||
|
String.format("""
|
||||||
|
Could not encoded particle param for particle %s.
|
||||||
|
This can indicated, that the wrong particle param is created in CraftParticle.
|
||||||
|
Particle param is of type %s.
|
||||||
|
""", bukkit.getKey(), particleParam.getClass()));
|
||||||
|
|
||||||
|
Optional<DataResult.PartialResult<NBTBase>> encodeError = encoded.error();
|
||||||
|
assertTrue(encodeError.isEmpty(), () -> String.format("""
|
||||||
|
Could not encoded particle param for particle %s.
|
||||||
|
This is possible because the wrong particle param is created in CraftParticle.
|
||||||
|
Particle param is of type %s.
|
||||||
|
Error message: %s.
|
||||||
|
""", bukkit.getKey(), particleParam.getClass(), encoded.error().get().message()));
|
||||||
|
|
||||||
|
Optional<NBTBase> encodeResult = encoded.result();
|
||||||
|
assertTrue(encodeResult.isPresent(), String.format("""
|
||||||
|
Result is not present for particle %s.
|
||||||
|
Even though there is also no error, this should not happen.
|
||||||
|
Particle param is of type %s.
|
||||||
|
""", bukkit.getKey(), particleParam.getClass()));
|
||||||
|
|
||||||
|
DataResult<T> decoded = minecraft.codec().parse(DynamicOpsNBT.INSTANCE, encodeResult.get());
|
||||||
|
|
||||||
|
Optional<DataResult.PartialResult<T>> decodeError = decoded.error();
|
||||||
|
assertTrue(decodeError.isEmpty(), () -> String.format("""
|
||||||
|
Could not decoded particle param for particle %s.
|
||||||
|
This is possible because the wrong particle param is created in CraftParticle.
|
||||||
|
Particle param is of type %s.
|
||||||
|
Error message: %s.
|
||||||
|
|
||||||
|
|
||||||
|
NBT data: %s.
|
||||||
|
""", bukkit.getKey(), particleParam.getClass(), decodeError.get().message(), encodeResult.get()));
|
||||||
|
|
||||||
|
Optional<T> decodeResult = decoded.result();
|
||||||
|
assertTrue(decodeResult.isPresent(), String.format("""
|
||||||
|
Result is not present for particle %s.
|
||||||
|
Even though there is also no error, this should not happen.
|
||||||
|
Particle param is of type %s.
|
||||||
|
""", bukkit.getKey(), particleParam.getClass()));
|
||||||
|
|
||||||
|
return assertInstanceOf(paramClass, decodeResult.get(), String.format("""
|
||||||
|
Result is not of the right type for particle %s.
|
||||||
|
""", bukkit.getKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user