diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index 5d38edd3..466eb141 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.ability; -import java.util.Optional; import java.util.Random; import javax.annotation.Nullable; @@ -20,8 +19,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.particle.ParticleTypes; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; +import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import net.minecraft.util.Pair; +import net.minecraft.util.TypedActionResult; import net.minecraft.util.math.Vec3d; /** @@ -48,7 +48,21 @@ public class UnicornCastingAbility implements Ability { @Override @Nullable public Hit tryActivate(Pony player) { - return getCostEstimate(player) <= player.getMagicalReserves().getMana().get() ? Hit.INSTANCE : null; + float manaLevel = player.getMagicalReserves().getMana().get(); + + TypedActionResult amulet = getAmulet(player); + + if (amulet.getResult().isAccepted()) { + return Hit.of(manaLevel > 0 && ((AmuletItem)amulet.getValue().getItem()).canCharge(amulet.getValue())); + } + + ActionResult spell = getNewSpell(player).getResult(); + + if (spell != ActionResult.PASS) { + return Hit.of(spell != ActionResult.FAIL && manaLevel > 4F); + } + + return Hit.of(manaLevel > (player.hasSpell() ? 2F : 4F)); } @Override @@ -58,62 +72,87 @@ public class UnicornCastingAbility implements Ability { @Override public double getCostEstimate(Pony player) { - return getAmulet(player) - .map(pair -> Math.min(player.getMagicalReserves().getMana().get(), pair.getLeft().getChargeRemainder(pair.getRight()))) - .orElseGet(() -> player.hasSpell() && getNewSpell(player).isPresent() ? 4F : 2F); + TypedActionResult amulet = getAmulet(player); + + if (amulet.getResult().isAccepted()) { + float manaLevel = player.getMagicalReserves().getMana().get(); + + return Math.min(manaLevel, ((AmuletItem)amulet.getValue().getItem()).getChargeRemainder(amulet.getValue())); + } + + if (getNewSpell(player).getResult() == ActionResult.CONSUME) { + return 4F; + } + + if (player.hasSpell()) { + return 2F; + } + + return 4F; } @Override public void apply(Pony player, Hit data) { - getAmulet(player).filter(pair -> { - float amount = -Math.min(player.getMagicalReserves().getMana().get(), pair.getLeft().getChargeRemainder(pair.getRight())); + TypedActionResult amulet = getAmulet(player); - if (amount < 0) { - AmuletItem.consumeEnergy(pair.getRight(), amount); - player.getMagicalReserves().getMana().add(amount * player.getMagicalReserves().getMana().getMax()); - player.getWorld().playSoundFromEntity(null, player.getMaster(), SoundEvents.BLOCK_END_PORTAL_FRAME_FILL, SoundCategory.PLAYERS, 1, 1); + if (amulet.getResult().isAccepted()) { + ItemStack stack = amulet.getValue(); + AmuletItem item = (AmuletItem)stack.getItem(); + + if (item.canCharge(stack)) { + float amount = -Math.min(player.getMagicalReserves().getMana().get(), item.getChargeRemainder(stack)); + + if (amount < 0) { + AmuletItem.consumeEnergy(stack, amount); + player.getMagicalReserves().getMana().add(amount * player.getMagicalReserves().getMana().getMax()); + player.getWorld().playSoundFromEntity(null, player.getMaster(), SoundEvents.BLOCK_END_PORTAL_FRAME_FILL, SoundCategory.PLAYERS, 1, 1); + } } - return true; - }).orElseGet(() -> { - Optional newSpell = getNewSpell(player); + } else { + TypedActionResult newSpell = getNewSpell(player); - @Nullable - Spell spell = player.hasSpell() ? newSpell.orElse(null) : newSpell.orElseGet(SpellType.SHIELD::create); + if (newSpell.getResult() != ActionResult.FAIL) { + @Nullable + Spell spell = newSpell.getValue(); + if (!player.hasSpell() && spell == null) { + spell = SpellType.SHIELD.create(); + } - player.subtractEnergyCost(spell == null ? 2 : 4); - player.setSpell(spell); - - return null; - }); + player.subtractEnergyCost(spell == null ? 2 : 4); + player.setSpell(spell); + } + } } - private Optional> getAmulet(Pony player) { + private TypedActionResult getAmulet(Pony player) { ItemStack stack = player.getMaster().getStackInHand(Hand.MAIN_HAND); if (stack.getItem() instanceof AmuletItem) { - AmuletItem amulet = (AmuletItem)stack.getItem(); - if (amulet.canCharge(stack)) { - return Optional.of(new Pair<>(amulet, stack)); - + if (((AmuletItem)stack.getItem()).isChargable()) { + return TypedActionResult.consume(stack); } + + return TypedActionResult.success(stack); } - return Optional.empty(); + return TypedActionResult.pass(stack); } - private Optional getNewSpell(Pony player) { + private TypedActionResult getNewSpell(Pony player) { final SpellType current = player.hasSpell() ? player.getSpell(true).getType() : null; return Streams.stream(player.getMaster().getItemsHand()) - .flatMap(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, i -> i instanceof Attached)) - .findFirst(); + .filter(GemstoneItem::isEnchanted) + .map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, i -> i instanceof Attached)) + .findFirst() + .orElse(TypedActionResult.pass(null)); } @Override public void preApply(Pony player, AbilitySlot slot) { player.getMagicalReserves().getEnergy().multiply(3.3F); - if (getAmulet(player).isPresent()) { + if (getAmulet(player).getResult() == ActionResult.CONSUME) { Vec3d eyes = player.getMaster().getCameraPosVec(1); float i = player.getAbilities().getStat(slot).getFillProgress(); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java index 374500c3..0a6a8884 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java @@ -1,17 +1,20 @@ package com.minelittlepony.unicopia.ability; -import java.util.Optional; +import javax.annotation.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; import com.minelittlepony.unicopia.ability.magic.Thrown; import com.minelittlepony.unicopia.ability.magic.spell.SpellType; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.GemstoneItem; import com.minelittlepony.unicopia.particle.MagicParticleEffect; +import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; /** * A magic casting ability for unicorns. @@ -45,7 +48,7 @@ public class UnicornProjectileAbility implements Ability { @Override public Hit tryActivate(Pony player) { - return Hit.INSTANCE; + return Hit.of(getNewSpell(player).getResult() != ActionResult.FAIL); } @Override @@ -60,15 +63,27 @@ public class UnicornProjectileAbility implements Ability { @Override public void apply(Pony player, Hit data) { - player.subtractEnergyCost(getCostEstimate(player)); - getThrown(player).orElseGet(SpellType.VORTEX::create).toss(player); + TypedActionResult thrown = getNewSpell(player); + + if (thrown.getResult() != ActionResult.FAIL) { + @Nullable + Thrown spell = (Thrown)thrown.getValue(); + + if (spell == null) { + spell = SpellType.VORTEX.create(); + } + + player.subtractEnergyCost(getCostEstimate(player)); + spell.toss(player); + } } - private Optional getThrown(Pony player) { + private TypedActionResult getNewSpell(Pony player) { return Streams.stream(player.getMaster().getItemsHand()) - .flatMap(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, i -> i instanceof Thrown)) - .map(Thrown.class::cast) - .findFirst(); + .filter(GemstoneItem::isEnchanted) + .map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, i -> i instanceof Thrown)) + .findFirst() + .orElse(TypedActionResult.pass(null)); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/data/Hit.java b/src/main/java/com/minelittlepony/unicopia/ability/data/Hit.java index 454b50c9..096e3e89 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/data/Hit.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/data/Hit.java @@ -7,6 +7,10 @@ public class Hit { public static final Hit INSTANCE = new Hit(); public static final Serializer SERIALIZER = buf -> INSTANCE; + public static Hit of(boolean value) { + return value ? INSTANCE : null; + } + protected Hit() { } diff --git a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java index 56e45614..3f1f8a68 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java @@ -3,7 +3,6 @@ package com.minelittlepony.unicopia.item; import java.util.List; import java.util.Objects; import java.util.function.Predicate; -import java.util.stream.Stream; import javax.annotation.Nullable; @@ -19,7 +18,9 @@ import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; +import net.minecraft.util.Hand; import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; @@ -67,20 +68,27 @@ public class GemstoneItem extends Item { return super.getName(); } - public static Stream consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType exclude, Predicate test) { + public static TypedActionResult consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType exclude, Predicate test) { + + if (!isEnchanted(stack)) { + return TypedActionResult.pass(null); + } + SpellType key = GemstoneItem.getSpellKey(stack); if (Objects.equals(key, exclude)) { - return Stream.empty(); + return TypedActionResult.fail(null); } Spell spell = key.create(getAffinity(stack)); if (spell == null || !test.test(spell)) { - return Stream.empty(); + return TypedActionResult.fail(null); } if (!player.world.isClient) { + player.swingHand(player.getStackInHand(Hand.OFF_HAND) == stack ? Hand.OFF_HAND : Hand.MAIN_HAND); + if (stack.getCount() == 1) { GemstoneItem.unenchanted(stack); } else { @@ -88,7 +96,7 @@ public class GemstoneItem extends Item { } } - return Stream.of(spell); + return TypedActionResult.consume(spell); } public static boolean isEnchanted(ItemStack stack) {