diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index 0aa798ec..1cc2e4e4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -7,7 +7,6 @@ import org.jetbrains.annotations.Nullable; import com.google.common.collect.Streams; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.data.Hit; -import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.entity.player.Pony; @@ -117,8 +116,11 @@ public class UnicornCastingAbility implements Ability { if (newSpell.getResult() != ActionResult.FAIL) { CustomisedSpellType spell = newSpell.getValue(); - player.subtractEnergyCost(spell.isEmpty() ? 2 : 4); - spell.apply(player); + boolean remove = player.getSpellSlot().removeIf(spell, true); + player.subtractEnergyCost(remove ? 2 : 4); + if (!remove) { + spell.apply(player); + } } } } @@ -139,12 +141,11 @@ public class UnicornCastingAbility implements Ability { } private TypedActionResult> getNewSpell(Pony player) { - final SpellType current = player.getSpellSlot().get(true).map(Spell::getType).orElse(SpellType.empty()); return Streams.stream(player.getMaster().getItemsHand()) .filter(GemstoneItem::isEnchanted) - .map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, null)) + .map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, null)) .findFirst() - .orElse(TypedActionResult.>pass((current == SpellType.EMPTY_KEY ? SpellType.SHIELD : SpellType.EMPTY_KEY).withTraits())); + .orElse(TypedActionResult.>pass(SpellType.SHIELD.withTraits())); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java index 2ec52c23..42d649ff 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java @@ -22,7 +22,9 @@ public interface SpellContainer { public void clear() { } @Override - public void removeIf(Predicate effect, boolean update) { } + public boolean removeIf(Predicate effect, boolean update) { + return false; + } @Override public boolean forEach(Function action, boolean update) { @@ -56,8 +58,10 @@ public interface SpellContainer { /** * Removes all matching active effects. + * + * @return True if the collection was changed */ - void removeIf(Predicate test, boolean update); + boolean removeIf(Predicate test, boolean update); /** * Iterates active spells and optionally removes matching ones. @@ -86,8 +90,8 @@ public interface SpellContainer { } @Override - default void removeIf(Predicate effect, boolean update) { - delegate().removeIf(effect, update); + default boolean removeIf(Predicate effect, boolean update) { + return delegate().removeIf(effect, update); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java index 77106780..5bb1837b 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CustomisedSpellType.java @@ -3,11 +3,11 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; -public class CustomisedSpellType { - +public class CustomisedSpellType implements SpellPredicate { private final SpellType type; private final SpellTraits traits; @@ -28,4 +28,9 @@ public class CustomisedSpellType { public T apply(Caster caster) { return type.apply(caster, traits); } + + @Override + public boolean test(Spell spell) { + return type.test(spell); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java b/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java index 4c379d1a..31e9e79b 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java +++ b/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.network.datasync; import java.util.Optional; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; @@ -61,28 +60,27 @@ public class EffectSync implements SpellContainer { } @Override - public void removeIf(Predicate test, boolean update) { - forEach(effect -> { - if (test.test(effect)) { - spells.removeReference(effect); + public boolean removeIf(Predicate test, boolean update) { + return reduce((initial, effect) -> { + if (!test.test(effect)) { + return initial; } + spells.removeReference(effect); + return true; }); } @Override public boolean forEach(Function test, boolean update) { - boolean[] matched = new boolean[1]; - - forEach(effect -> { + return reduce((initial, effect) -> { Operation op = test.apply(effect); if (op == Operation.REMOVE) { spells.removeReference(effect); } else { - matched[0] |= op != Operation.SKIP; + initial |= op != Operation.SKIP; } + return initial; }); - - return matched[0]; } @Override @@ -103,10 +101,16 @@ public class EffectSync implements SpellContainer { return spells.getReferences(); } - public void forEach(Consumer consumer) { + public boolean reduce(Alteration alteration) { spells.fromNbt(owner.getEntity().getDataTracker().get(param)); - spells.getReferences().toList().forEach(consumer); + + boolean initial = false; + for (Spell i : spells.getReferences().toList()) { + initial = alteration.apply(initial, i); + } + write(); + return initial; } private void write() { @@ -118,4 +122,8 @@ public class EffectSync implements SpellContainer { public interface UpdateCallback { void onSpellSet(@Nullable Spell spell); } + + private interface Alteration { + boolean apply(boolean initial, Spell item); + } }