diff --git a/api/src/main/java/com/seibel/lod/api/enums/config/DisallowSelectingViaConfigGui.java b/api/src/main/java/com/seibel/lod/api/enums/config/DisallowSelectingViaConfigGui.java
new file mode 100644
index 000000000..ef5798d58
--- /dev/null
+++ b/api/src/main/java/com/seibel/lod/api/enums/config/DisallowSelectingViaConfigGui.java
@@ -0,0 +1,17 @@
+package com.seibel.lod.api.enums.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Add this annotation to enum values that
+ * are valid config options, but shouldn't be selectable
+ * when toggling through the options.
+ *
+ * Example: A preset's "custom" option shouldn't be selectable
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DisallowSelectingViaConfigGui
+{
+
+}
diff --git a/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EQualityPreset.java b/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EQualityPreset.java
index f73e76009..4445fc7e2 100644
--- a/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EQualityPreset.java
+++ b/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EQualityPreset.java
@@ -19,6 +19,8 @@
package com.seibel.lod.api.enums.config.quickOptions;
+import com.seibel.lod.api.enums.config.DisallowSelectingViaConfigGui;
+
/**
* CUSTOM,
*
@@ -34,6 +36,7 @@ public enum EQualityPreset
// when adding items up the API minor version
// when removing items up the API major version
+ @DisallowSelectingViaConfigGui
CUSTOM,
MINIMUM,
diff --git a/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EThreadPreset.java b/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EThreadPreset.java
index e45136d73..3ca6f7409 100644
--- a/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EThreadPreset.java
+++ b/api/src/main/java/com/seibel/lod/api/enums/config/quickOptions/EThreadPreset.java
@@ -19,6 +19,8 @@
package com.seibel.lod.api.enums.config.quickOptions;
+import com.seibel.lod.api.enums.config.DisallowSelectingViaConfigGui;
+
/**
* CUSTOM,
*
@@ -34,6 +36,7 @@ public enum EThreadPreset
// when adding items up the API minor version
// when removing items up the API major version
+ @DisallowSelectingViaConfigGui
CUSTOM,
MINIMAL_IMPACT,
diff --git a/core/src/main/java/com/seibel/lod/core/util/AnnotationUtil.java b/core/src/main/java/com/seibel/lod/core/util/AnnotationUtil.java
new file mode 100644
index 000000000..e5e480328
--- /dev/null
+++ b/core/src/main/java/com/seibel/lod/core/util/AnnotationUtil.java
@@ -0,0 +1,45 @@
+package com.seibel.lod.core.util;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.lang.reflect.Field;
+
+public class AnnotationUtil
+{
+ private static final Logger LOGGER = LogManager.getLogger();
+
+
+ /** A quick method to test if an enum value has specific runtime annotation. */
+ public static , TAnno extends java.lang.annotation.Annotation> boolean doesEnumHaveAnnotation(TEnum enumValue, Class annotationToSearchFor)
+ {
+ try
+ {
+ // fields will contain all possible enums
+ // unfortunately James isn't sure of a way to do this without looping through all enum values
+ // (although since enums should only have ~10 items at most, this shouldn't be a big deal)
+ Field[] fields = enumValue.getClass().getFields();
+ for (Field field : fields)
+ {
+ // only test for annotations for the
+ @SuppressWarnings("unchecked")
+ TEnum testEnumValue = (TEnum) field.get(enumValue);
+ if (testEnumValue == enumValue)
+ {
+ return field.getAnnotation(annotationToSearchFor) != null;
+ }
+ }
+
+ // should never happen
+ // if we got here Java screwed up getting us the enums
+ throw new IllegalStateException("Enum missing expected value. Enum: ["+enumValue.getClass()+"] doesn't contain the value: ["+enumValue.name()+"].");
+ }
+ catch (IllegalAccessException | IllegalArgumentException | ClassCastException e)
+ {
+ // shouldn't happen, but just in case
+ LOGGER.error("Unable to get annotation for enum: ["+enumValue.getClass()+"]. Unexpected exception: ["+e+"], message: ["+e.getMessage()+"].", e);
+ return false;
+ }
+ }
+
+}