From c02440a48f0259fcb2dd82ee5c503edd47d686ec Mon Sep 17 00:00:00 2001
From: MrHell228 <artemkz2016@gmail.com>
Date: Thu, 13 Jun 2024 20:31:38 +0300
Subject: [PATCH 1/3] fix particles

---
 .../api/effect/particle/ParticleOptions.java  | 56 +++++++++++--------
 1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/src/main/java/org/spongepowered/api/effect/particle/ParticleOptions.java b/src/main/java/org/spongepowered/api/effect/particle/ParticleOptions.java
index 36f8859c20..c9e3a59c95 100644
--- a/src/main/java/org/spongepowered/api/effect/particle/ParticleOptions.java
+++ b/src/main/java/org/spongepowered/api/effect/particle/ParticleOptions.java
@@ -27,7 +27,6 @@
 import org.spongepowered.api.ResourceKey;
 import org.spongepowered.api.Sponge;
 import org.spongepowered.api.block.BlockState;
-import org.spongepowered.api.effect.potion.PotionEffectType;
 import org.spongepowered.api.item.inventory.ItemStackSnapshot;
 import org.spongepowered.api.registry.DefaultedRegistryReference;
 import org.spongepowered.api.registry.Registry;
@@ -36,8 +35,8 @@
 import org.spongepowered.api.registry.RegistryScopes;
 import org.spongepowered.api.registry.RegistryTypes;
 import org.spongepowered.api.util.Color;
-import org.spongepowered.api.util.Direction;
 import org.spongepowered.api.util.Ticks;
+import org.spongepowered.api.world.PositionSource;
 import org.spongepowered.math.vector.Vector3d;
 
 /**
@@ -57,8 +56,9 @@ public final class ParticleOptions {
      *
      * <ul>
      *   <li>{@link ParticleTypes#BLOCK}</li>
+     *   <li>{@link ParticleTypes#BLOCK_MARKER}</li>
+     *   <li>{@link ParticleTypes#DUST_PILLAR}</li>
      *   <li>{@link ParticleTypes#FALLING_DUST}</li>
-     *   <li>{@link ParticleTypes#ITEM}</li>
      * </ul>
      */
     public static final DefaultedRegistryReference<ParticleOption<BlockState>> BLOCK_STATE = ParticleOptions.key(ResourceKey.sponge("block_state"));
@@ -70,13 +70,14 @@ public final class ParticleOptions {
      * <ul>
      *   <li>{@link ParticleTypes#ENTITY_EFFECT}</li>
      *   <li>{@link ParticleTypes#DUST}</li>
+     *   <li>{@link ParticleTypes#DUST_COLOR_TRANSITION}</li>
      * </ul>
      */
     public static final DefaultedRegistryReference<ParticleOption<Color>> COLOR = ParticleOptions.key(ResourceKey.sponge("color"));
 
     /**
      * This option will affect the delay of particles that are spawned.
-     * The only vanilla {@link ParticleType}s this option isn't applicable to are:
+     * The only vanilla {@link ParticleType} this option is applicable to is:
      *
      * <ul>
      *   <li>{@link ParticleTypes#SHRIEK}</li>
@@ -85,19 +86,25 @@ public final class ParticleOptions {
     public static final DefaultedRegistryReference<ParticleOption<Integer>> DELAY = ParticleOptions.key(ResourceKey.sponge("delay"));
 
     /**
-     * This option will change the direction of a particle.
+     * This option will affect the destination of a particle.
+     * The only vanilla {@link ParticleType} this option is applicable to is:
+     *
+     * <ul>
+     *   <li>{@link ParticleTypes#VIBRATION}</li>
+     * </ul>
      */
-    public static final DefaultedRegistryReference<ParticleOption<Direction>> DIRECTION = ParticleOptions.key(ResourceKey.sponge("direction"));
+    public static final DefaultedRegistryReference<ParticleOption<PositionSource>> DESTINATION = ParticleOptions.key(ResourceKey.sponge("destination"));
 
     /**
      * This option will affect the appearance of a particle. The only vanilla
-     * {@link ParticleType} this option is applicable to are:
+     * {@link ParticleType} this option is applicable to is:
      *
      * <ul>
-     *   <li>{@link ParticleTypes#BLOCK}</li>
-     *   <li>{@link ParticleTypes#FALLING_DUST}</li>
      *   <li>{@link ParticleTypes#ITEM}</li>
      * </ul>
+     *
+     * <p>The item stack snapshot may never be empty, or a {@link IllegalArgumentException}
+     * will be thrown when applying</p>
      */
     public static final DefaultedRegistryReference<ParticleOption<ItemStackSnapshot>> ITEM_STACK_SNAPSHOT = ParticleOptions.key(ResourceKey.sponge("item_stack_snapshot"));
 
@@ -107,21 +114,21 @@ public final class ParticleOptions {
     public static final DefaultedRegistryReference<ParticleOption<Vector3d>> OFFSET = ParticleOptions.key(ResourceKey.sponge("offset"));
 
     /**
-     * This option will change the potion type of a particle. The only vanilla
-     * {@link ParticleType}s this option is applicable to is
-     */
-    public static final DefaultedRegistryReference<ParticleOption<PotionEffectType>> POTION_EFFECT_TYPE = ParticleOptions.key(ResourceKey.sponge("potion_effect_type"));
-
-    /**
-     * This option will affect the amount of particles that are spawned. The
-     * minimum amount of particles is 1. The only vanilla {@link ParticleType}s
-     * this option isn't applicable to are:
+     * This option will affect the opacity of a particle.
+     * The only vanilla {@link ParticleType} this option is applicable to is:
      *
      * <ul>
-     *   <li>{@link ParticleTypes#BLOCK}</li>
-     *   <li>{@link ParticleTypes#FIREWORK}</li>
+     *   <li>{@link ParticleTypes#ENTITY_EFFECT}</li>
      * </ul>
      *
+     * <p>The opacity must be between 0 and 1, or a {@link IllegalArgumentException}
+     * will be thrown when applying.</p>
+     */
+    public static final DefaultedRegistryReference<ParticleOption<Double>> OPACITY = ParticleOptions.key(ResourceKey.sponge("opacity"));
+
+    /**
+     * This option will affect the amount of particles that are spawned.
+     *
      * <p>The quantity must be at least 1, or a {@link IllegalArgumentException}
      * will be thrown when applying.</p>
      */
@@ -129,7 +136,7 @@ public final class ParticleOptions {
 
     /**
      * This option will change the roll of a particle. The only
-     * vanilla {@link ParticleType}s this option is applicable to is:
+     * vanilla {@link ParticleType} this option is applicable to is:
      *
      * <ul>
      *   <li>{@link ParticleTypes#SCULK_CHARGE}</li>
@@ -139,10 +146,11 @@ public final class ParticleOptions {
 
     /**
      * This option will change the scale of a particle. The only
-     * vanilla {@link ParticleType}s this option is applicable to is:
+     * vanilla {@link ParticleType}s this option is applicable to are:
      *
      * <ul>
      *   <li>{@link ParticleTypes#DUST}</li>
+     *   <li>{@link ParticleTypes#DUST_COLOR_TRANSITION}</li>
      * </ul>
      *
      * <p>The scale may never be negative, or a {@link IllegalArgumentException}
@@ -152,7 +160,7 @@ public final class ParticleOptions {
 
     /**
      * This option will change the color the transition particle will change to.
-     * The only vanilla {@link ParticleType}s this option is applicable to is:
+     * The only vanilla {@link ParticleType} this option is applicable to is:
      *
      * <ul>
      *   <li>{@link ParticleTypes#DUST_COLOR_TRANSITION}</li>
@@ -162,7 +170,7 @@ public final class ParticleOptions {
 
     /**
      * This option will change the travel time of a particle.
-     * The only vanilla {@link ParticleType}s this option is applicable to is:
+     * The only vanilla {@link ParticleType} this option is applicable to is:
      *
      * <ul>
      *   <li>{@link ParticleTypes#VIBRATION}</li>

From e3c9433608f0aae2820b1b48e742cca5405bc2f2 Mon Sep 17 00:00:00 2001
From: MrHell228 <artemkz2016@gmail.com>
Date: Thu, 13 Jun 2024 21:44:29 +0300
Subject: [PATCH 2/3] Add PositionSource

---
 .../api/world/PositionSource.java             | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 src/main/java/org/spongepowered/api/world/PositionSource.java

diff --git a/src/main/java/org/spongepowered/api/world/PositionSource.java b/src/main/java/org/spongepowered/api/world/PositionSource.java
new file mode 100644
index 0000000000..554aa2c818
--- /dev/null
+++ b/src/main/java/org/spongepowered/api/world/PositionSource.java
@@ -0,0 +1,86 @@
+/*
+ * This file is part of SpongeAPI, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) SpongePowered <https://www.spongepowered.org>
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package org.spongepowered.api.world;
+
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.entity.Entity;
+import org.spongepowered.math.vector.Vector3i;
+
+public interface PositionSource {
+
+    /**
+     * Creates {@link PositionSource} for provided position.
+     *
+     * @param position The position
+     * @return The position source
+     */
+    static PositionSource of(Vector3i position) {
+        return Sponge.game().factoryProvider().provide(Factory.class).of(position);
+    }
+
+    /**
+     * Creates {@link PositionSource} for provided position.
+     *
+     * @param x The x position
+     * @param y The y position
+     * @param z The z position
+     * @return The position source
+     */
+    static PositionSource of(int x, int y, int z) {
+        return Sponge.game().factoryProvider().provide(Factory.class).of(x, y, z);
+    }
+
+    /**
+     * Creates {@link PositionSource} for provided entity.
+     *
+     * @param entity The entity
+     * @return The position source
+     */
+    static PositionSource of(Entity entity) {
+        return Sponge.game().factoryProvider().provide(Factory.class).of(entity);
+    }
+
+    /**
+     * Creates {@link PositionSource} for provided entity and vertical offset.
+     *
+     * @param entity The entity
+     * @param yOffset The vertical offset
+     * @return The position source
+     */
+    static PositionSource of(Entity entity, double yOffset) {
+        return Sponge.game().factoryProvider().provide(Factory.class).of(entity, yOffset);
+    }
+
+    interface Factory {
+
+        PositionSource of(Vector3i position);
+
+        PositionSource of(int x, int y, int z);
+
+        PositionSource of(Entity entity);
+
+        PositionSource of(Entity entity, double yOffset);
+    }
+}

From 0c9df112f0f90ef3096e9f39e473061a24c07f4b Mon Sep 17 00:00:00 2001
From: MrHell228 <artemkz2016@gmail.com>
Date: Mon, 17 Jun 2024 03:36:37 +0300
Subject: [PATCH 3/3] Add PositionSource description

---
 src/main/java/org/spongepowered/api/world/PositionSource.java | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/main/java/org/spongepowered/api/world/PositionSource.java b/src/main/java/org/spongepowered/api/world/PositionSource.java
index 554aa2c818..29ab78be57 100644
--- a/src/main/java/org/spongepowered/api/world/PositionSource.java
+++ b/src/main/java/org/spongepowered/api/world/PositionSource.java
@@ -28,6 +28,10 @@
 import org.spongepowered.api.entity.Entity;
 import org.spongepowered.math.vector.Vector3i;
 
+/**
+ * In some particle implementations, they can "follow" a source that moves over
+ * several ticks such that a singular position is not enough information to follow.
+ */
 public interface PositionSource {
 
     /**
