From 94d81ff5f5ff8c72f48eb3daf342f928037e14ae Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 23 Sep 2022 16:05:04 +0200 Subject: [PATCH] Fix server exception when earth ponies try to kick things. Fixes #63 --- .../unicopia/ability/Ability.java | 23 ++++++++++- .../unicopia/ability/AbilityDispatcher.java | 11 ++--- .../ability/EarthPonyKickAbility.java | 41 +++++++++++-------- .../ability/UnicornCastingAbility.java | 2 +- .../unicopia/network/MsgPlayerAbility.java | 8 ++-- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/Ability.java b/src/main/java/com/minelittlepony/unicopia/ability/Ability.java index b604379d..0aa73e2d 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/Ability.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/Ability.java @@ -1,5 +1,7 @@ package com.minelittlepony.unicopia.ability; +import java.util.Optional; + import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.Race; @@ -33,10 +35,22 @@ public interface Ability { *

* @return True if the event has been handled. */ + default boolean onQuickAction(Pony player, ActivationType type, Optional data) { + return onQuickAction(player, type); + } + + @Deprecated default boolean onQuickAction(Pony player, ActivationType type) { return false; } + /** + * Called on the client to get any data required for the quick action. + */ + default Optional prepareQuickAction(Pony player, ActivationType type) { + return Optional.empty(); + } + /** * Called to check preconditions for activating the ability. * @@ -54,14 +68,19 @@ public interface Ability { */ boolean canUse(Race playerSpecies); + @Deprecated + @Nullable + T tryActivate(Pony player); + /** * Called on the client to activate the ability. * * @param player The player activating the ability * @return Data to be sent, or null if activation failed */ - @Nullable - T tryActivate(Pony player); + default Optional prepare(Pony player) { + return Optional.ofNullable(tryActivate(player)); + } Hit.Serializer getSerializer(); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java b/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java index 4d66e3f3..a020cb15 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java @@ -44,9 +44,10 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable { } } - private boolean triggerQuickAction(Ability ability, ActivationType pressType) { - if (ability.onQuickAction(player, pressType)) { - Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, null, pressType)); + private boolean triggerQuickAction(Ability ability, ActivationType pressType) { + Optional data = ability.prepareQuickAction(player, pressType); + if (ability.onQuickAction(player, pressType, data)) { + Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data, pressType)); return true; } return false; @@ -206,9 +207,9 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable { setCooldown(ability.getCooldownTime(player)); if (player.isClientPlayer()) { - T data = ability.tryActivate(player); + Optional data = ability.prepare(player); - if (data != null) { + if (data.isPresent()) { Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data, ActivationType.NONE)); } else { player.getEntity().playSound(USounds.GUI_ABILITY_FAIL, 1, 1); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java index 4b1c7410..c831eae5 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia.ability; import java.util.List; +import java.util.Optional; import org.jetbrains.annotations.Nullable; @@ -65,29 +66,34 @@ public class EarthPonyKickAbility implements Ability { } @Override - public boolean onQuickAction(Pony player, ActivationType type) { + public Optional prepareQuickAction(Pony player, ActivationType type) { + return Optional.of(getDefaultKickLocation(player)); + } + + @Override + public boolean onQuickAction(Pony player, ActivationType type, Optional data) { if (type == ActivationType.TAP) { if (!player.isClient()) { - Vec3d origin = player.getOriginVector(); + data.ifPresent(kickLocation -> { + Vec3d origin = player.getOriginVector(); + World w = player.getReferenceWorld(); - Pos kickLocation = getDefaultKickLocation(player); - World w = player.getReferenceWorld(); - - for (var e : VecHelper.findInRange(player.getEntity(), w, kickLocation.vec(), 2, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR)) { - if (e instanceof LivingEntity entity) { - float calculatedStrength = 0.5F * (1 + player.getLevel().getScaled(9)); - entity.damage(MagicalDamageSource.KICK, player.getReferenceWorld().random.nextBetween(2, 10) + calculatedStrength); - entity.takeKnockback(calculatedStrength, origin.x - entity.getX(), origin.z - entity.getZ()); - player.subtractEnergyCost(3); - player.setAnimation(Animation.KICK); - return true; + for (var e : VecHelper.findInRange(player.getEntity(), w, kickLocation.vec(), 2, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR)) { + if (e instanceof LivingEntity entity) { + float calculatedStrength = 0.5F * (1 + player.getLevel().getScaled(9)); + entity.damage(MagicalDamageSource.KICK, player.getReferenceWorld().random.nextBetween(2, 10) + calculatedStrength); + entity.takeKnockback(calculatedStrength, origin.x - entity.getX(), origin.z - entity.getZ()); + player.subtractEnergyCost(3); + player.setAnimation(Animation.KICK); + return; + } } - } - BlockPos pos = kickLocation.pos(); - EarthPonyStompAbility.stompBlock(w, pos, 10 * (1 + player.getLevel().getScaled(5)) * w.getBlockState(pos).calcBlockBreakingDelta(player.getMaster(), w, pos)); - player.setAnimation(Animation.KICK); + BlockPos pos = kickLocation.pos(); + EarthPonyStompAbility.stompBlock(w, pos, 10 * (1 + player.getLevel().getScaled(5)) * w.getBlockState(pos).calcBlockBreakingDelta(player.getMaster(), w, pos)); + player.setAnimation(Animation.KICK); + }); } return true; @@ -112,6 +118,7 @@ public class EarthPonyKickAbility implements Ability { private Pos getDefaultKickLocation(Pony player) { Vec3d kickVector = player.getMaster().getRotationVector().multiply(1, 0, 1); + player.getMaster(); if (!MineLPDelegate.getInstance().getPlayerPonyRace(player.getMaster()).isDefault()) { kickVector = kickVector.rotateY((float)Math.PI); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index a60a1d9d..aa2ec307 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -23,7 +23,7 @@ import net.minecraft.sound.SoundCategory; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.*; import net.minecraft.util.math.random.Random; /** diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java b/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java index b479666e..f53f51ea 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java @@ -2,8 +2,6 @@ package com.minelittlepony.unicopia.network; import java.util.Optional; -import org.jetbrains.annotations.Nullable; - import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.ability.Ability; import com.minelittlepony.unicopia.ability.ActivationType; @@ -29,9 +27,9 @@ public class MsgPlayerAbility implements Packet power, @Nullable T data, ActivationType type) { + public MsgPlayerAbility(Ability power, Optional data, ActivationType type) { this.power = power; - this.data = Optional.ofNullable(data); + this.data = data; this.type = type; } @@ -50,7 +48,7 @@ public class MsgPlayerAbility implements Packet power.canApply(player, data)).ifPresentOrElse( data -> power.apply(player, data),