mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Flightly fix the logic for when the cast abilities should fail
This commit is contained in:
parent
c5fdb9167f
commit
a50cc0d117
4 changed files with 111 additions and 45 deletions
|
@ -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<Hit> {
|
|||
@Override
|
||||
@Nullable
|
||||
public Hit tryActivate(Pony player) {
|
||||
return getCostEstimate(player) <= player.getMagicalReserves().getMana().get() ? Hit.INSTANCE : null;
|
||||
float manaLevel = player.getMagicalReserves().getMana().get();
|
||||
|
||||
TypedActionResult<ItemStack> 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<Hit> {
|
|||
|
||||
@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<ItemStack> 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<ItemStack> 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<Spell> newSpell = getNewSpell(player);
|
||||
} else {
|
||||
TypedActionResult<Spell> 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<Pair<AmuletItem, ItemStack>> getAmulet(Pony player) {
|
||||
private TypedActionResult<ItemStack> 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<Spell> getNewSpell(Pony player) {
|
||||
private TypedActionResult<Spell> 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.<Spell>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();
|
||||
|
|
|
@ -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<Hit> {
|
|||
|
||||
@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<Hit> {
|
|||
|
||||
@Override
|
||||
public void apply(Pony player, Hit data) {
|
||||
player.subtractEnergyCost(getCostEstimate(player));
|
||||
getThrown(player).orElseGet(SpellType.VORTEX::create).toss(player);
|
||||
TypedActionResult<Spell> 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<Thrown> getThrown(Pony player) {
|
||||
private TypedActionResult<Spell> 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.<Spell>pass(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,10 @@ public class Hit {
|
|||
public static final Hit INSTANCE = new Hit();
|
||||
public static final Serializer<Hit> SERIALIZER = buf -> INSTANCE;
|
||||
|
||||
public static Hit of(boolean value) {
|
||||
return value ? INSTANCE : null;
|
||||
}
|
||||
|
||||
protected Hit() {
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Spell> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, Predicate<Spell> test) {
|
||||
public static TypedActionResult<Spell> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, Predicate<Spell> test) {
|
||||
|
||||
if (!isEnchanted(stack)) {
|
||||
return TypedActionResult.pass(null);
|
||||
}
|
||||
|
||||
SpellType<Spell> 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) {
|
||||
|
|
Loading…
Reference in a new issue