Unicopia/src/main/java/com/minelittlepony/unicopia/ability/AbilityDispatcher.java

141 lines
3.8 KiB
Java
Raw Normal View History

package com.minelittlepony.unicopia.ability;
import java.util.Optional;
2018-09-12 01:29:49 +02:00
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.ability.data.Hit;
import com.minelittlepony.unicopia.entity.Updatable;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.network.MsgPlayerAbility;
import com.minelittlepony.unicopia.network.Channel;
2020-04-15 18:12:00 +02:00
import com.minelittlepony.unicopia.util.NbtSerialisable;
2018-09-12 01:29:49 +02:00
2020-01-16 12:35:46 +01:00
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Identifier;
2018-09-12 01:29:49 +02:00
public class AbilityDispatcher implements Updatable, NbtSerialisable {
2018-09-12 01:29:49 +02:00
2020-04-15 18:12:00 +02:00
private final Pony player;
2018-09-12 01:29:49 +02:00
2019-02-03 10:45:45 +01:00
/**
* Ticks of warmup before an ability is triggered.
*/
private int warmup;
2018-09-12 01:29:49 +02:00
2019-02-03 10:45:45 +01:00
/**
* Ticks of cooldown after an ability has been triggered.
*/
private int cooldown;
/**
* True once the current ability has been triggered.
*/
private boolean triggered;
2018-09-12 01:29:49 +02:00
private Optional<Ability<?>> activeAbility = Optional.empty();
2018-09-12 01:29:49 +02:00
public AbilityDispatcher(Pony player) {
2018-09-12 01:29:49 +02:00
this.player = player;
}
2019-02-03 10:45:45 +01:00
/**
* Returns true if the currrent ability can we swapped out.
*/
2018-09-12 01:29:49 +02:00
boolean canSwitchStates() {
return !activeAbility.isPresent() || (warmup != 0) || (triggered && cooldown == 0);
2018-09-12 01:29:49 +02:00
}
2020-04-15 17:22:29 +02:00
public void tryUseAbility(Ability<?> power) {
2019-02-03 10:45:45 +01:00
if (canSwitchStates()) {
setAbility(power);
2018-09-12 01:29:49 +02:00
}
}
2019-02-03 10:45:45 +01:00
public void tryClearAbility() {
if (canSwitchStates()) {
2019-02-03 10:45:45 +01:00
setAbility(null);
}
}
protected synchronized void setAbility(Ability<?> power) {
if (activeAbility.orElse(null) != power) {
2019-02-03 16:43:37 +01:00
triggered = false;
activeAbility = Optional.ofNullable(power);
warmup = activeAbility.map(p -> p.getWarmupTime(player)).orElse(0);
2018-09-12 01:29:49 +02:00
cooldown = 0;
}
}
2019-02-03 10:45:45 +01:00
@Nullable
protected synchronized Optional<Ability<?>> getUsableAbility() {
return activeAbility.filter(ability -> {
return (triggered && warmup == 0 && cooldown == 0) && ability.canUse(player.getSpecies());
});
2019-02-03 10:45:45 +01:00
}
2018-09-12 01:29:49 +02:00
public int getRemainingCooldown() {
return cooldown;
}
@Override
2019-02-17 18:22:11 +01:00
public void onUpdate() {
getUsableAbility().ifPresent(this::activate);
}
private <T extends Hit> void activate(Ability<T> ability) {
2019-02-03 10:45:45 +01:00
if (warmup > 0) {
warmup--;
ability.preApply(player);
return;
}
if (cooldown > 0) {
cooldown--;
ability.postApply(player);
return;
}
if (triggered) {
return;
}
if (ability.canActivate(player.getWorld(), player)) {
triggered = true;
cooldown = ability.getCooldownTime(player);
if (player.isClientPlayer()) {
T data = ability.tryActivate(player);
if (data != null) {
Channel.PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data));
} else {
cooldown = 0;
}
2018-09-12 01:29:49 +02:00
}
}
2019-02-03 10:45:45 +01:00
if (cooldown <= 0) {
setAbility(null);
}
2018-09-12 01:29:49 +02:00
}
@Override
2020-01-16 12:35:46 +01:00
public void toNBT(CompoundTag compound) {
compound.putBoolean("triggered", triggered);
compound.putInt("warmup", warmup);
compound.putInt("cooldown", cooldown);
getUsableAbility().ifPresent(ability -> {
compound.putString("activeAbility", Abilities.REGISTRY.getId(ability).toString());
});
2018-09-12 01:29:49 +02:00
}
@Override
2020-01-16 12:35:46 +01:00
public void fromNBT(CompoundTag compound) {
2019-02-03 10:45:45 +01:00
triggered = compound.getBoolean("triggered");
2020-01-16 12:35:46 +01:00
warmup = compound.getInt("warmup");
cooldown = compound.getInt("cooldown");
activeAbility = Abilities.REGISTRY.getOrEmpty(new Identifier(compound.getString("activeAbility")));
2018-09-12 01:29:49 +02:00
}
}