69 lines
2.4 KiB
Java
69 lines
2.4 KiB
Java
package games.dmg.spigottyrant;
|
|
|
|
import java.time.Duration;
|
|
import java.time.Instant;
|
|
import java.util.EnumMap;
|
|
import java.util.EnumSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
public final class AbilityReadinessService {
|
|
public PlayerState consume(
|
|
PlayerState player,
|
|
Ability ability,
|
|
Instant now,
|
|
Duration cooldown
|
|
) {
|
|
if (!player.readyAbilityItems().contains(ability)) {
|
|
throw new IllegalStateException("ability item is not ready");
|
|
}
|
|
if (ability == Ability.TAMER_CAPTURE && cooldown.isZero()) {
|
|
return player;
|
|
}
|
|
Set<Ability> ready = EnumSet.noneOf(Ability.class);
|
|
ready.addAll(player.readyAbilityItems());
|
|
ready.remove(ability);
|
|
Map<Ability, Instant> cooldowns = new EnumMap<>(Ability.class);
|
|
cooldowns.putAll(player.cooldownEnds());
|
|
cooldowns.put(ability, now.plus(cooldown));
|
|
return copy(player, cooldowns, ready);
|
|
}
|
|
|
|
public PlayerState refresh(PlayerState player, Instant now) {
|
|
Map<Ability, Instant> cooldowns = new EnumMap<>(Ability.class);
|
|
cooldowns.putAll(player.cooldownEnds());
|
|
Set<Ability> ready = EnumSet.noneOf(Ability.class);
|
|
ready.addAll(player.readyAbilityItems());
|
|
for (Map.Entry<Ability, Instant> entry : player.cooldownEnds().entrySet()) {
|
|
if (!entry.getValue().isAfter(now)) {
|
|
cooldowns.remove(entry.getKey());
|
|
if (isItemAbilityForClass(entry.getKey(), player.tyrantClass())) {
|
|
ready.add(entry.getKey());
|
|
}
|
|
}
|
|
}
|
|
return copy(player, cooldowns, ready);
|
|
}
|
|
|
|
private static boolean isItemAbilityForClass(Ability ability, TyrantClass tyrantClass) {
|
|
return switch (tyrantClass) {
|
|
case ASSASSIN -> ability == Ability.ASSASSIN_INVISIBILITY;
|
|
case FIXER -> ability == Ability.FIXER_BOOST;
|
|
case TAMER -> ability == Ability.TAMER_CAPTURE;
|
|
case NONE -> false;
|
|
};
|
|
}
|
|
|
|
private static PlayerState copy(
|
|
PlayerState player,
|
|
Map<Ability, Instant> cooldowns,
|
|
Set<Ability> ready
|
|
) {
|
|
return new PlayerState(
|
|
player.playerId(), player.latestName(), player.lastLogin(), player.optedOutUntil(),
|
|
player.tyrantClass(), player.followerOf(), cooldowns, ready,
|
|
player.capturedMobs()
|
|
);
|
|
}
|
|
}
|