mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-17 10:24:23 +01:00
Fix server exception when earth ponies try to kick things. Fixes #63
This commit is contained in:
parent
a53cb275e9
commit
94d81ff5f5
5 changed files with 55 additions and 30 deletions
|
@ -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<T extends Hit> {
|
|||
* <p>
|
||||
* @return True if the event has been handled.
|
||||
*/
|
||||
default boolean onQuickAction(Pony player, ActivationType type, Optional<T> 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<T> prepareQuickAction(Pony player, ActivationType type) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to check preconditions for activating the ability.
|
||||
*
|
||||
|
@ -54,14 +68,19 @@ public interface Ability<T extends Hit> {
|
|||
*/
|
||||
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<T> prepare(Pony player) {
|
||||
return Optional.ofNullable(tryActivate(player));
|
||||
}
|
||||
|
||||
Hit.Serializer<T> getSerializer();
|
||||
|
||||
|
|
|
@ -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 <T extends Hit> boolean triggerQuickAction(Ability<T> ability, ActivationType pressType) {
|
||||
Optional<T> 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<T> 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);
|
||||
|
|
|
@ -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<Pos> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onQuickAction(Pony player, ActivationType type) {
|
||||
public Optional<Pos> prepareQuickAction(Pony player, ActivationType type) {
|
||||
return Optional.of(getDefaultKickLocation(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQuickAction(Pony player, ActivationType type, Optional<Pos> 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<Pos> {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<T extends Hit> implements Packet<ServerPlayerEntit
|
|||
type = ActivationType.of(buffer.readInt());
|
||||
}
|
||||
|
||||
public MsgPlayerAbility(Ability<T> power, @Nullable T data, ActivationType type) {
|
||||
public MsgPlayerAbility(Ability<T> power, Optional<T> data, ActivationType type) {
|
||||
this.power = power;
|
||||
this.data = Optional.ofNullable(data);
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
@ -50,7 +48,7 @@ public class MsgPlayerAbility<T extends Hit> implements Packet<ServerPlayerEntit
|
|||
}
|
||||
|
||||
if (type != ActivationType.NONE) {
|
||||
power.onQuickAction(player, type);
|
||||
power.onQuickAction(player, type, data);
|
||||
} else {
|
||||
data.filter(data -> power.canApply(player, data)).ifPresentOrElse(
|
||||
data -> power.apply(player, data),
|
||||
|
|
Loading…
Reference in a new issue