feat(participation): highlight opted-out players
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.ScoreboardManager;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
public final class OptOutGlowController implements Runnable, Listener {
|
||||
private static final String TEAM_NAME = "tyrant-optout";
|
||||
private final TyrantStateManager stateManager;
|
||||
private final Server server;
|
||||
private final PluginSettings settings;
|
||||
private final Scoreboard scoreboard;
|
||||
private final Team greenTeam;
|
||||
private final Map<UUID, PreviousPresentation> managed = new HashMap<>();
|
||||
|
||||
public OptOutGlowController(
|
||||
TyrantStateManager stateManager,
|
||||
Server server,
|
||||
PluginSettings settings
|
||||
) {
|
||||
this.stateManager = stateManager;
|
||||
this.server = server;
|
||||
this.settings = settings;
|
||||
ScoreboardManager manager = Objects.requireNonNull(
|
||||
server.getScoreboardManager(), "Scoreboard manager is unavailable"
|
||||
);
|
||||
scoreboard = manager.getMainScoreboard();
|
||||
Team existing = scoreboard.getTeam(TEAM_NAME);
|
||||
greenTeam = existing == null ? scoreboard.registerNewTeam(TEAM_NAME) : existing;
|
||||
greenTeam.setColor(ChatColor.GREEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
GameState game = stateManager.game();
|
||||
Player tyrant = game.tyrantId().map(server::getPlayer).orElse(null);
|
||||
boolean tyrantAvailable = tyrant != null && !tyrant.isDead();
|
||||
Set<UUID> online = new HashSet<>();
|
||||
for (Player player : server.getOnlinePlayers()) {
|
||||
online.add(player.getUniqueId());
|
||||
PlayerState state = stateManager.players().get(player.getUniqueId());
|
||||
boolean sameWorld = tyrantAvailable && !player.isDead()
|
||||
&& player.getWorld().equals(tyrant.getWorld());
|
||||
double distanceSquared = sameWorld
|
||||
? player.getLocation().distanceSquared(tyrant.getLocation())
|
||||
: Double.POSITIVE_INFINITY;
|
||||
boolean shouldGlow = state != null && OptOutGlowPolicy.shouldGlow(
|
||||
game, state, tyrantAvailable, sameWorld, distanceSquared,
|
||||
settings.tyrantRangeBlocks()
|
||||
);
|
||||
if (shouldGlow && !managed.containsKey(player.getUniqueId())) {
|
||||
apply(player);
|
||||
} else if (!shouldGlow && managed.containsKey(player.getUniqueId())) {
|
||||
restore(player.getUniqueId(), player);
|
||||
}
|
||||
}
|
||||
for (UUID playerId : Set.copyOf(managed.keySet())) {
|
||||
if (!online.contains(playerId) && server.getPlayer(playerId) == null) {
|
||||
restore(playerId, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
if (managed.containsKey(event.getPlayer().getUniqueId())) {
|
||||
restore(event.getPlayer().getUniqueId(), event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAll() {
|
||||
for (UUID playerId : Set.copyOf(managed.keySet())) {
|
||||
restore(playerId, server.getPlayer(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
private void apply(Player player) {
|
||||
Team previousTeam = scoreboard.getEntryTeam(player.getName());
|
||||
if (previousTeam == greenTeam) {
|
||||
previousTeam = null;
|
||||
}
|
||||
managed.put(
|
||||
player.getUniqueId(),
|
||||
new PreviousPresentation(player.getName(), previousTeam, player.isGlowing())
|
||||
);
|
||||
greenTeam.addEntry(player.getName());
|
||||
player.setGlowing(true);
|
||||
}
|
||||
|
||||
private void restore(UUID playerId, Player player) {
|
||||
PreviousPresentation previous = managed.remove(playerId);
|
||||
if (previous == null) {
|
||||
return;
|
||||
}
|
||||
greenTeam.removeEntry(previous.playerName());
|
||||
if (previous.team() != null) {
|
||||
try {
|
||||
previous.team().addEntry(previous.playerName());
|
||||
} catch (IllegalStateException ignored) {
|
||||
// The prior team was removed while this plugin managed the entry.
|
||||
}
|
||||
}
|
||||
if (player != null) {
|
||||
player.setGlowing(previous.glowing());
|
||||
}
|
||||
}
|
||||
|
||||
private record PreviousPresentation(
|
||||
String playerName,
|
||||
Team team,
|
||||
boolean glowing
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
public final class OptOutGlowPolicy {
|
||||
private OptOutGlowPolicy() {
|
||||
}
|
||||
|
||||
public static boolean shouldGlow(
|
||||
GameState game,
|
||||
PlayerState player,
|
||||
boolean tyrantAvailable,
|
||||
boolean playerAvailableInTyrantWorld,
|
||||
double distanceSquared,
|
||||
double rangeBlocks
|
||||
) {
|
||||
return game.lifecycle() == GameLifecycle.RUNNING
|
||||
&& game.tyrantId().isPresent()
|
||||
&& player.optedOutUntil().isPresent()
|
||||
&& tyrantAvailable
|
||||
&& playerAvailableInTyrantWorld
|
||||
&& distanceSquared <= rangeBlocks * rangeBlocks;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
private AssassinEffectController assassinEffects;
|
||||
private FixerEffectController fixerEffects;
|
||||
private TyrantEffectController tyrantEffects;
|
||||
private OptOutGlowController optOutGlow;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -69,6 +70,7 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
FixerAbilityService fixerAbilities = new FixerAbilityService(readiness, settings);
|
||||
fixerEffects = new FixerEffectController(stateManager, getServer(), settings, clock);
|
||||
tyrantEffects = new TyrantEffectController(stateManager, getServer(), settings);
|
||||
optOutGlow = new OptOutGlowController(stateManager, getServer(), settings);
|
||||
VigilanteCombatTracker combatTracker = new VigilanteCombatTracker();
|
||||
vigilanteEffects = new VigilanteEffectController(
|
||||
stateManager, getServer(), combatTracker, settings, clock
|
||||
@@ -128,6 +130,7 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
),
|
||||
this
|
||||
);
|
||||
getServer().getPluginManager().registerEvents(optOutGlow, this);
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new VigilanteCombatListener(
|
||||
stateManager, combatTracker, clock, settings.vigilanteCombatDuration()
|
||||
@@ -176,6 +179,7 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
getServer().getScheduler().runTaskTimer(this, assassinEffects, 10L, 10L);
|
||||
getServer().getScheduler().runTaskTimer(this, fixerEffects, 10L, 10L);
|
||||
getServer().getScheduler().runTaskTimer(this, tyrantEffects, 10L, 10L);
|
||||
getServer().getScheduler().runTaskTimer(this, optOutGlow, 10L, 10L);
|
||||
getServer().getScheduler().runTaskTimer(
|
||||
this,
|
||||
new AbilityItemRefreshTask(
|
||||
@@ -191,6 +195,9 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (optOutGlow != null) {
|
||||
optOutGlow.clearAll();
|
||||
}
|
||||
if (tyrantEffects != null) {
|
||||
tyrantEffects.clearAll();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user