Send quick-time actions to the server so they can work properly

This commit is contained in:
Sollace 2021-12-31 16:17:41 +02:00
parent de1b597ab7
commit c84fda37c4
4 changed files with 41 additions and 18 deletions

View file

@ -28,7 +28,7 @@ public interface Ability<T extends Hit> {
int getCooldownTime(Pony player);
/**
* Called on the client when an ability is about to be triggered.
* Called when an ability is about to be triggered. This event occurs on both the client and server so check {@code Pony#isClient} if you need to know which one you're on.
* <p>
* Use this method to respond to quick-time events, like short taps or double-taps.
* <p>

View file

@ -40,12 +40,20 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
Stat stat = getStat(slot);
if (stat.canSwitchStates()) {
if (pressType == ActivationType.NONE || stat.getAbility(page).filter(ability -> ability.onQuickAction(player, pressType)).isEmpty()) {
if (pressType == ActivationType.NONE || stat.getAbility(page).filter(ability -> !triggerQuickAction(ability, pressType)).isEmpty()) {
stat.setActiveAbility(null);
}
}
}
private boolean triggerQuickAction(Ability<?> ability, ActivationType pressType) {
if (ability.onQuickAction(player, pressType)) {
Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, null, pressType));
return true;
}
return false;
}
public Optional<Ability<?>> activate(AbilitySlot slot, long page) {
Stat stat = getStat(slot);
if (stat.canSwitchStates()) {
@ -199,7 +207,7 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
T data = ability.tryActivate(player);
if (data != null) {
Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data));
Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data, ActivationType.NONE));
} else {
player.getEntity().playSound(SoundEvents.BLOCK_NOTE_BLOCK_DIDGERIDOO, 1, 1);
setCooldown(0);

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.ability;
import net.minecraft.util.math.MathHelper;
public enum ActivationType {
NONE,
TAP,
@ -15,4 +17,8 @@ public enum ActivationType {
public int getTapCount() {
return ordinal();
}
}
public static ActivationType of(int id) {
return VALUES[MathHelper.clamp(id, 0, VALUES.length)];
}
}

View file

@ -1,12 +1,16 @@
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;
import com.minelittlepony.unicopia.ability.data.Hit;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.util.network.Packet;
import com.minelittlepony.unicopia.ability.Abilities;
import net.minecraft.util.Identifier;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity;
@ -14,26 +18,28 @@ import net.minecraft.server.network.ServerPlayerEntity;
* Sent to the server when a player activates an ability.
*/
public class MsgPlayerAbility<T extends Hit> implements Packet<ServerPlayerEntity> {
private final Ability<T> power;
private final T data;
private final Optional<T> data;
private final ActivationType type;
@SuppressWarnings("unchecked")
MsgPlayerAbility(PacketByteBuf buffer) {
power = (Ability<T>) Abilities.REGISTRY.get(new Identifier(buffer.readString(32767)));
data = power.getSerializer().fromBuffer(buffer);
power = (Ability<T>) Abilities.REGISTRY.get(buffer.readIdentifier());
data = buffer.readOptional(power.getSerializer()::fromBuffer);
type = ActivationType.of(buffer.readInt());
}
public MsgPlayerAbility(Ability<T> power, T data) {
public MsgPlayerAbility(Ability<T> power, @Nullable T data, ActivationType type) {
this.power = power;
this.data = data;
this.data = Optional.ofNullable(data);
this.type = type;
}
@Override
public void toBuffer(PacketByteBuf buffer) {
buffer.writeString(Abilities.REGISTRY.getId(power).toString());
data.toBuffer(buffer);
buffer.writeIdentifier(Abilities.REGISTRY.getId(power));
buffer.writeOptional(data, (buf, t) -> t.toBuffer(buf));
buffer.writeInt(type.ordinal());
}
@Override
@ -43,10 +49,13 @@ public class MsgPlayerAbility<T extends Hit> implements Packet<ServerPlayerEntit
return;
}
if (!power.canApply(player, data)) {
Channel.CANCEL_PLAYER_ABILITY.send(sender, new MsgCancelPlayerAbility());
if (type != ActivationType.NONE) {
power.onQuickAction(player, type);
} else {
power.apply(player, data);
data.filter(data -> power.canApply(player, data)).ifPresentOrElse(
data -> power.apply(player, data),
() -> Channel.CANCEL_PLAYER_ABILITY.send(sender, new MsgCancelPlayerAbility())
);
}
}
}