diff --git a/api/src/main/java/com/seibel/distanthorizons/api/interfaces/util/IDhApiCopyable.java b/api/src/main/java/com/seibel/distanthorizons/api/interfaces/util/IDhApiCopyable.java
new file mode 100644
index 000000000..4a86357ef
--- /dev/null
+++ b/api/src/main/java/com/seibel/distanthorizons/api/interfaces/util/IDhApiCopyable.java
@@ -0,0 +1,18 @@
+package com.seibel.distanthorizons.api.interfaces.util;
+
+/**
+ * Used for objects that need deep clones.
+ * Replacement for {@link Cloneable}.
+ *
+ * @see Cloneable
+ *
+ * @author James Seibel
+ * @version 2024-7-12
+ * @since API 3.0.0
+ */
+public interface IDhApiCopyable
+{
+ /** Returns a deep clone of all parameters whenever possible. */
+ IDhApiCopyable copy();
+
+}
diff --git a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java
index f1d9156a5..01b8fcaa1 100644
--- a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java
+++ b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
+import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
@@ -52,7 +53,7 @@ public abstract class DhApiBeforeBufferRenderEvent implements IDhApiEvent
@@ -33,7 +35,7 @@ package com.seibel.distanthorizons.api.objects.math;
* @author James Seibel
* @version 2024-6-30
*/
-public class DhApiMat4f
+public class DhApiMat4f implements IDhApiCopyable
{
public float m00;
public float m01;
@@ -277,7 +279,6 @@ public class DhApiMat4f
this.m33 *= scalar;
}
- public DhApiMat4f copy() { return new DhApiMat4f(this); }
@@ -384,4 +385,7 @@ public class DhApiMat4f
this.m30 + " " + this.m31 + " " + this.m32 + " " + this.m33 + "\n";
}
+ @Override
+ public DhApiMat4f copy() { return new DhApiMat4f(this); }
+
}
diff --git a/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiVec3f.java b/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiVec3f.java
index 5fa60d8d1..8120b149a 100644
--- a/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiVec3f.java
+++ b/api/src/main/java/com/seibel/distanthorizons/api/objects/math/DhApiVec3f.java
@@ -19,6 +19,8 @@
package com.seibel.distanthorizons.api.objects.math;
+import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
+
/**
* Often used to store block positions or any other
* position in 3D space.
@@ -27,7 +29,7 @@ package com.seibel.distanthorizons.api.objects.math;
* @version 2024-6-3
* @since API 2.2.0
*/
-public class DhApiVec3f
+public class DhApiVec3f implements IDhApiCopyable
{
public float x;
public float y;
@@ -90,4 +92,7 @@ public class DhApiVec3f
@Override
public String toString() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }
+ @Override
+ public DhApiVec3f copy() { return new DhApiVec3f(this.x, this.y, this.z); }
+
}
diff --git a/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/ApiEventInjector.java b/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/ApiEventInjector.java
index e6d49f611..386ab2aef 100644
--- a/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/ApiEventInjector.java
+++ b/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/ApiEventInjector.java
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.coreapi.DependencyInjection;
import com.seibel.distanthorizons.api.interfaces.events.IDhApiEventInjector;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
+import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiOneTimeEvent;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
@@ -140,7 +141,26 @@ public class ApiEventInjector extends DependencyInjector implements
// fire each event and record if any of them
// request to cancel the event.
- DhApiEventParam eventParam = createEventParamWrapper(event, eventInput);
+
+ // attempt to clone the event input if possible
+ // this is done to reduce the likely hood that one event listener
+ // will make change the event parameter for other listeners
+ T input = eventInput;
+ if (eventInput instanceof IDhApiEventParam)
+ {
+ try
+ {
+ //noinspection unchecked
+ input = (T) ((IDhApiEventParam) eventInput).copy();
+ }
+ catch (Exception e)
+ {
+ LOGGER.error("Unable to clone event parameter ["+eventInput.getClass().getSimpleName()+"], error: ["+e.getMessage()+"].", e);
+ }
+ }
+
+
+ DhApiEventParam eventParam = createEventParamWrapper(event, input);
event.fireEvent(eventParam);
if (eventParam instanceof DhApiCancelableEventParam)