diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml
index c460957..5d0bdaa 100644
--- a/config/checkstyle/suppression.xml
+++ b/config/checkstyle/suppression.xml
@@ -8,7 +8,10 @@
+
+
+
\ No newline at end of file
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/EcoArmorPlugin.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/EcoArmorPlugin.java
index 3d8006b..c0596c1 100644
--- a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/EcoArmorPlugin.java
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/EcoArmorPlugin.java
@@ -11,6 +11,7 @@ import com.willfp.ecoarmor.commands.TabcompleterEagive;
import com.willfp.ecoarmor.display.ArmorDisplay;
import com.willfp.ecoarmor.effects.Effect;
import com.willfp.ecoarmor.effects.Effects;
+import com.willfp.ecoarmor.effects.util.EffectWatcher;
import com.willfp.ecoarmor.sets.ArmorSets;
import com.willfp.ecoarmor.sets.util.EffectiveDurabilityListener;
import com.willfp.ecoarmor.sets.util.PotionEffectListener;
@@ -139,7 +140,8 @@ public class EcoArmorPlugin extends AbstractEcoPlugin {
new AdvancementShardListener(this),
new PotionEffectListener(this),
new EffectiveDurabilityListener(this),
- new DiscoverRecipeListener(this)
+ new DiscoverRecipeListener(this),
+ new EffectWatcher(this)
);
}
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/Condition.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/Condition.java
new file mode 100644
index 0000000..936fe1c
--- /dev/null
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/Condition.java
@@ -0,0 +1,57 @@
+package com.willfp.ecoarmor.conditions;
+
+import com.willfp.ecoarmor.EcoArmorPlugin;
+import lombok.AccessLevel;
+import lombok.Getter;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class Condition implements Listener {
+ /**
+ * Instance of EcoArmor.
+ */
+ @Getter(AccessLevel.PROTECTED)
+ private final EcoArmorPlugin plugin = EcoArmorPlugin.getInstance();
+
+ /**
+ * The name of the effect.
+ */
+ @Getter
+ private final String name;
+
+ /**
+ * The class of the config getter type.
+ */
+ @Getter
+ private final Class typeClass;
+
+ /**
+ * Create a new condition.
+ *
+ * @param name The condition name.
+ * @param typeClass The class of the config type.
+ */
+ protected Condition(@NotNull final String name,
+ @NotNull final Class typeClass) {
+ this.name = name;
+ this.typeClass = typeClass;
+
+ Conditions.addNewCondition(this);
+ }
+
+ /**
+ * Get if condition is met for a player.
+ *
+ * @param player The player.
+ * @param value The value of the condition.
+ * @return If met.
+ */
+ public final boolean isMet(@NotNull final Player player,
+ @NotNull final Object value) {
+ return isConditionMet(player, typeClass.cast(value));
+ }
+
+ protected abstract boolean isConditionMet(@NotNull Player player,
+ @NotNull T value);
+}
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/Conditions.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/Conditions.java
new file mode 100644
index 0000000..0d22f0d
--- /dev/null
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/Conditions.java
@@ -0,0 +1,50 @@
+package com.willfp.ecoarmor.conditions;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.ImmutableList;
+import com.willfp.ecoarmor.conditions.conditions.ConditionBelowY;
+import lombok.experimental.UtilityClass;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+@UtilityClass
+@SuppressWarnings("unused")
+public class Conditions {
+ /**
+ * All registered effects.
+ */
+ private static final BiMap> BY_NAME = HashBiMap.create();
+
+ public static final Condition> BELOW_Y = new ConditionBelowY();
+
+ /**
+ * Get condition matching name.
+ *
+ * @param name The name to query.
+ * @return The matching condition, or null if not found.
+ */
+ public static Condition> getByName(@NotNull final String name) {
+ return BY_NAME.get(name);
+ }
+
+ /**
+ * List of all registered conditions.
+ *
+ * @return The conditions.
+ */
+ public static List> values() {
+ return ImmutableList.copyOf(BY_NAME.values());
+ }
+
+ /**
+ * Add new condition to EcoArmor.
+ *
+ * @param condition The condition to add.
+ */
+ public static void addNewCondition(@NotNull final Condition> condition) {
+ BY_NAME.remove(condition.getName());
+ BY_NAME.put(condition.getName(), condition);
+ }
+}
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/conditions/ConditionBelowY.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/conditions/ConditionBelowY.java
new file mode 100644
index 0000000..cd8f8f1
--- /dev/null
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/conditions/conditions/ConditionBelowY.java
@@ -0,0 +1,44 @@
+package com.willfp.ecoarmor.conditions.conditions;
+
+import com.willfp.ecoarmor.conditions.Condition;
+import com.willfp.ecoarmor.sets.ArmorSet;
+import com.willfp.ecoarmor.sets.util.ArmorUtils;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class ConditionBelowY extends Condition {
+ public ConditionBelowY() {
+ super("below-y", Double.class);
+ }
+
+ @EventHandler
+ public void listener(@NotNull final PlayerMoveEvent event) {
+ Player player = event.getPlayer();
+
+ ArmorSet set = ArmorUtils.getSetOnPlayer(player);
+
+ if (set == null) {
+ return;
+ }
+
+ Double value = set.getConditionValue(this);
+
+ if (value == null) {
+ return;
+ }
+
+ if (isMet(player, value)) {
+ set.getEffects().keySet().forEach(effect -> effect.enable(player));
+ } else {
+ set.getEffects().keySet().forEach(effect -> effect.disable(player));
+ }
+ }
+
+ @Override
+ public boolean isConditionMet(@NotNull final Player player,
+ @NotNull final Double value) {
+ return player.getLocation().getY() < value;
+ }
+}
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/Effect.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/Effect.java
index ff88a3c..2ee6abc 100644
--- a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/Effect.java
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/Effect.java
@@ -3,9 +3,12 @@ package com.willfp.ecoarmor.effects;
import com.willfp.ecoarmor.EcoArmorPlugin;
import lombok.AccessLevel;
import lombok.Getter;
+import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
+import java.util.HashSet;
+import java.util.Set;
import java.util.UUID;
public abstract class Effect implements Listener {
@@ -39,6 +42,11 @@ public abstract class Effect implements Listener {
@Getter
private final Class typeClass;
+ /**
+ * Players that the effect is currently enabled for.
+ */
+ private final Set enabledPlayers = new HashSet<>();
+
/**
* Create a new effect.
*
@@ -54,6 +62,53 @@ public abstract class Effect implements Listener {
update();
Effects.addNewEffect(this);
}
+ /**
+ * Get if effect is enabled for player.
+ *
+ * @param player The player.
+ * @return If enabled.
+ */
+ public final boolean isEnabledForPlayer(@NotNull final Player player) {
+ return enabledPlayers.contains(player.getUniqueId());
+ }
+
+ /**
+ * Enable the effect for a player.
+ *
+ * @param player The player.
+ */
+ public final void enable(@NotNull final Player player) {
+ if (enabledPlayers.contains(player.getUniqueId())) {
+ return;
+ }
+
+ enabledPlayers.add(player.getUniqueId());
+
+ this.onEnable(player);
+ }
+
+ /**
+ * Disable the effect for a player.
+ *
+ * @param player The player.
+ */
+ public final void disable(@NotNull final Player player) {
+ if (!enabledPlayers.contains(player.getUniqueId())) {
+ return;
+ }
+
+ enabledPlayers.remove(player.getUniqueId());
+
+ this.onDisable(player);
+ }
+
+ protected void onEnable(@NotNull final Player player) {
+ // Empty by default
+ }
+
+ protected void onDisable(@NotNull final Player player) {
+ // Empty by default
+ }
/**
* Update if the effect is enabled.
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/effects/SpeedMultiplier.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/effects/SpeedMultiplier.java
index 127a872..acdc6e5 100644
--- a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/effects/SpeedMultiplier.java
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/effects/SpeedMultiplier.java
@@ -1,13 +1,11 @@
package com.willfp.ecoarmor.effects.effects;
-import com.willfp.eco.util.events.armorequip.ArmorEquipEvent;
import com.willfp.ecoarmor.effects.Effect;
import com.willfp.ecoarmor.sets.util.ArmorUtils;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.NotNull;
public class SpeedMultiplier extends Effect {
@@ -15,23 +13,28 @@ public class SpeedMultiplier extends Effect {
super("speed-multiplier", Double.class);
}
- @EventHandler
- public void listener(@NotNull final ArmorEquipEvent event) {
- Player player = event.getPlayer();
-
+ @Override
+ protected void onEnable(@NotNull final Player player) {
AttributeInstance movementSpeed = player.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
assert movementSpeed != null;
- this.getPlugin().getScheduler().runLater(() -> {
- Double multiplier = ArmorUtils.getEffectStrength(player, this);
- if (multiplier == null) {
- movementSpeed.removeModifier(new AttributeModifier(this.getUuid(), "speed-multiplier", 0, AttributeModifier.Operation.MULTIPLY_SCALAR_1));
- } else {
- AttributeModifier modifier = new AttributeModifier(this.getUuid(), "speed-multiplier", multiplier - 1, AttributeModifier.Operation.MULTIPLY_SCALAR_1);
- if (!movementSpeed.getModifiers().contains(modifier)) {
- movementSpeed.addModifier(modifier);
- }
- }
- }, 1);
+ Double strength = ArmorUtils.getEffectStrength(player, this);
+
+ if (strength == null) {
+ return;
+ }
+
+ AttributeModifier modifier = new AttributeModifier(this.getUuid(), "speed-multiplier", strength - 1, AttributeModifier.Operation.MULTIPLY_SCALAR_1);
+ if (!movementSpeed.getModifiers().contains(modifier)) {
+ movementSpeed.addModifier(modifier);
+ }
+ }
+
+ @Override
+ protected void onDisable(@NotNull final Player player) {
+ AttributeInstance movementSpeed = player.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
+ assert movementSpeed != null;
+
+ movementSpeed.removeModifier(new AttributeModifier(this.getUuid(), "speed-multiplier", 0, AttributeModifier.Operation.MULTIPLY_SCALAR_1));
}
}
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/util/EffectWatcher.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/util/EffectWatcher.java
new file mode 100644
index 0000000..97e3795
--- /dev/null
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/effects/util/EffectWatcher.java
@@ -0,0 +1,60 @@
+package com.willfp.ecoarmor.effects.util;
+
+import com.willfp.eco.util.events.armorequip.ArmorEquipEvent;
+import com.willfp.eco.util.internal.PluginDependent;
+import com.willfp.eco.util.plugin.AbstractEcoPlugin;
+import com.willfp.ecoarmor.effects.Effect;
+import com.willfp.ecoarmor.effects.Effects;
+import com.willfp.ecoarmor.sets.ArmorSet;
+import com.willfp.ecoarmor.sets.util.ArmorUtils;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.jetbrains.annotations.NotNull;
+
+public class EffectWatcher extends PluginDependent implements Listener {
+ /**
+ * Pass an {@link AbstractEcoPlugin} in order to interface with it.
+ *
+ * @param plugin The plugin to manage.
+ */
+ public EffectWatcher(@NotNull final AbstractEcoPlugin plugin) {
+ super(plugin);
+ }
+
+ /**
+ * Listener for armor equipping.
+ *
+ * @param event The event to listen for.
+ */
+ @EventHandler
+ public void armorEquipListener(@NotNull final ArmorEquipEvent event) {
+ Player player = event.getPlayer();
+
+ this.getPlugin().getScheduler().runLater(() -> {
+ ArmorSet set = ArmorUtils.getSetOnPlayer(player);
+
+ for (Effect> effect : Effects.values()) {
+ boolean enabled = true;
+
+ if (set == null) {
+ enabled = false;
+ } else {
+ if (set.getEffectStrength(effect) == null) {
+ enabled = false;
+ }
+
+ if (ArmorUtils.areConditionsMet(player)) {
+ enabled = false;
+ }
+ }
+
+ if (enabled) {
+ effect.enable(player);
+ } else {
+ effect.disable(player);
+ }
+ }
+ }, 1);
+ }
+}
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/ArmorSet.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/ArmorSet.java
index 652d717..ffc0519 100644
--- a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/ArmorSet.java
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/ArmorSet.java
@@ -8,6 +8,8 @@ import com.willfp.eco.util.recipe.RecipeParts;
import com.willfp.eco.util.recipe.parts.ComplexRecipePart;
import com.willfp.eco.util.recipe.recipes.EcoShapedRecipe;
import com.willfp.ecoarmor.EcoArmorPlugin;
+import com.willfp.ecoarmor.conditions.Condition;
+import com.willfp.ecoarmor.conditions.Conditions;
import com.willfp.ecoarmor.effects.Effect;
import com.willfp.ecoarmor.effects.Effects;
import com.willfp.ecoarmor.sets.meta.ArmorSlot;
@@ -55,6 +57,12 @@ public class ArmorSet {
@Getter(AccessLevel.PRIVATE)
private final AbstractUndefinedConfig config;
+ /**
+ * Conditions and their values.
+ */
+ @Getter
+ private final Map, Object> conditions = new HashMap<>();
+
/**
* Effects and their strengths.
*/
@@ -115,6 +123,14 @@ public class ArmorSet {
this.config = config;
this.name = name;
+ for (String definedKey : this.getConfig().getStrings("conditions")) {
+ String[] split = definedKey.split(":");
+ String key = split[0].trim();
+ String value = split[1].trim();
+ Condition> condition = Conditions.getByName(key);
+ conditions.put(condition, ArmorUtils.getConditionValue(value, condition));
+ }
+
for (String definedKey : this.getConfig().getStrings("set-bonus")) {
String[] split = definedKey.split(":");
String key = split[0].trim();
@@ -324,6 +340,18 @@ public class ArmorSet {
return advancedItems.get(slot);
}
+ /**
+ * Get condition value of effect.
+ *
+ * @param condition The condition to query.
+ * @param The type of the condition value.
+ * @return The value.
+ */
+ @Nullable
+ public T getConditionValue(@NotNull final Condition condition) {
+ return (T) conditions.get(condition);
+ }
+
/**
* Get effect strength of effect.
*
diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/util/ArmorUtils.java b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/util/ArmorUtils.java
index a802f56..8c6dc21 100644
--- a/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/util/ArmorUtils.java
+++ b/eco-core/core-plugin/src/main/java/com/willfp/ecoarmor/sets/util/ArmorUtils.java
@@ -1,6 +1,7 @@
package com.willfp.ecoarmor.sets.util;
import com.willfp.ecoarmor.EcoArmorPlugin;
+import com.willfp.ecoarmor.conditions.Condition;
import com.willfp.ecoarmor.effects.Effect;
import com.willfp.ecoarmor.sets.ArmorSet;
import com.willfp.ecoarmor.sets.ArmorSets;
@@ -20,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
@UtilityClass
@@ -133,6 +135,46 @@ public class ArmorUtils {
return getEffectStrength(player, effect) != null;
}
+ /**
+ * Get the value of a condition on a player's set.
+ *
+ * @param player The player to test.
+ * @param condition The condition to test.
+ * @param Condition type.
+ * @return The value or null if not found.
+ */
+ @Nullable
+ public T getConditionValue(@NotNull final Player player,
+ @NotNull final Condition condition) {
+ ArmorSet set = getSetOnPlayer(player);
+ if (set == null) {
+ return null;
+ }
+
+ return set.getConditionValue(condition);
+ }
+
+ /**
+ * Get if all conditions are met for a player.
+ *
+ * @param player The player.
+ * @return If conditions are men.
+ */
+ public boolean areConditionsMet(@NotNull final Player player) {
+ ArmorSet set = getSetOnPlayer(player);
+ if (set == null) {
+ return true;
+ }
+
+ for (Map.Entry, Object> entry : set.getConditions().entrySet()) {
+ if (!entry.getKey().isMet(player, entry.getValue())) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
/**
* Get tier on upgrade crystal.
*
@@ -184,7 +226,7 @@ public class ArmorUtils {
* Set tier on item.
*
* @param itemStack The item to check.
- * @param tier The tier to set.
+ * @param tier The tier to set.
*/
public static void setTier(@NotNull final ItemStack itemStack,
@NotNull final Tier tier) {
@@ -382,4 +424,30 @@ public class ArmorUtils {
return string;
}
+
+ /**
+ * Get value of condition.
+ *
+ * @param string Value as string.
+ * @param condition Condition.
+ * @param The type of the condition.
+ * @return Value.
+ */
+ @NotNull
+ public static Object getConditionValue(@NotNull final String string,
+ @NotNull final Condition condition) {
+ if (condition.getTypeClass().equals(Boolean.class)) {
+ return Boolean.parseBoolean(string);
+ }
+
+ if (condition.getTypeClass().equals(Integer.class)) {
+ return Integer.parseInt(string);
+ }
+
+ if (condition.getTypeClass().equals(Double.class)) {
+ return Double.parseDouble(string);
+ }
+
+ return string;
+ }
}
diff --git a/eco-core/core-plugin/src/main/resources/sets/young.yml b/eco-core/core-plugin/src/main/resources/sets/young.yml
index 16d7c26..fe99704 100644
--- a/eco-core/core-plugin/src/main/resources/sets/young.yml
+++ b/eco-core/core-plugin/src/main/resources/sets/young.yml
@@ -1,4 +1,6 @@
enabled: true
+conditions:
+ - "below-y: 40"
set-bonus:
- "speed-multiplier: 1.25"
advanced-set-bonus: