Skip to content

Commit

Permalink
Add team color module
Browse files Browse the repository at this point in the history
  • Loading branch information
Redned235 committed Jul 13, 2024
1 parent acae0c6 commit a2df3be
Show file tree
Hide file tree
Showing 19 changed files with 263 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -30,7 +29,7 @@ public class Classes implements ArenaModuleInitializer {

public static final EventActionType<EquipClassAction> EQUIP_CLASS_ACTION = EventActionType.create("equip-class", EquipClassAction.class, EquipClassAction::new);
public static final ArenaOptionType<BooleanArenaOption> CLASS_EQUIPPING_OPTION = ArenaOptionType.create("class-equipping", BooleanArenaOption::new);
public static final ArenaOptionType<BooleanArenaOption> CLASS_EQUIP_ONLY_SELECTS = ArenaOptionType.create("class-equip-only-selects", BooleanArenaOption::new);
public static final ArenaOptionType<BooleanArenaOption> CLASS_EQUIP_ONLY_SELECTS_OPTION = ArenaOptionType.create("class-equip-only-selects", BooleanArenaOption::new);

private ArenaClasses classes;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void equip(Player player, @Argument(name = "class") ArenaClass arenaClass
.map(BooleanArenaOption::isEnabled)
.orElse(false);
if (canEquip) {
boolean equipOnlySelects = arenaPlayer.getCompetition().option(Classes.CLASS_EQUIP_ONLY_SELECTS)
boolean equipOnlySelects = arenaPlayer.getCompetition().option(Classes.CLASS_EQUIP_ONLY_SELECTS_OPTION)
.map(BooleanArenaOption::isEnabled)
.orElse(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void call(ArenaPlayer arenaPlayer, Resolvable resolvable) {
arenaPlayer.getPlayer().getInventory().clear();
}

boolean equipOnlySelects = arenaPlayer.getCompetition().option(Classes.CLASS_EQUIP_ONLY_SELECTS)
boolean equipOnlySelects = arenaPlayer.getCompetition().option(Classes.CLASS_EQUIP_ONLY_SELECTS_OPTION)
.map(BooleanArenaOption::isEnabled)
.orElse(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class PlayerListLineCreator implements ScoreboardLineCreator {
private int maxEntries;

@ArenaOption(name = "show-team-color", description = "Whether to show the team color of the player.")
private boolean showTeamColor;
private boolean showTeamColor = true;

@ArenaOption(name = "require-alive", description = "Whether to only show alive players.")
private boolean requireAlive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class TopStatLineCreator implements ScoreboardLineCreator {
private boolean ascending;

@ArenaOption(name = "show-team-color", description = "Whether to show the team color of the player.")
private boolean showTeamColor;
private boolean showTeamColor = true;

@SuppressWarnings("unchecked")
@Override
Expand Down
13 changes: 10 additions & 3 deletions module/scoreboards/src/main/resources/scoreboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ templates:
lines:
- " "
- "<yellow>Players: <white>%online_players%/%max_players%"
- "<yellow>Map: <white>%map%"
- " "
- "<white>battleplugins.org"
ingame-list:
Expand All @@ -41,9 +42,11 @@ templates:
lines:
- " "
- "<yellow>Map: <white>%map%"
- "<yellow>Time remaining: <white>%time_remaining_short%"
- " "
- "<yellow>Players:"
- player-list:
max-entries: 10
max-entries: 8
- simple:
lines:
- " "
Expand All @@ -56,9 +59,11 @@ templates:
lines:
- " "
- "<yellow>Map: <white>%map%"
- "<yellow>Time remaining: <white>%time_remaining_short%"
- " "
- "<yellow>Alive players:"
- player-list:
max-entries: 10
max-entries: 8
require-alive: true
- simple:
lines:
Expand All @@ -72,10 +77,12 @@ templates:
lines:
- " "
- "<yellow>Map: <white>%map%"
- "<yellow>Time remaining: <white>%time_remaining_short%"
- " "
- "<yellow>Top kills:"
- top-stat:
stat: kills
max-entries: 10
max-entries: 8
- simple:
lines:
- " "
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package org.battleplugins.arena.module.teamcolors;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.battleplugins.arena.ArenaPlayer;
import org.battleplugins.arena.BattleArena;
import org.battleplugins.arena.competition.LiveCompetition;
import org.battleplugins.arena.event.arena.ArenaPhaseStartEvent;
import org.battleplugins.arena.event.player.ArenaJoinEvent;
import org.battleplugins.arena.event.player.ArenaLeaveEvent;
import org.battleplugins.arena.event.player.ArenaTeamJoinEvent;
import org.battleplugins.arena.event.player.ArenaTeamLeaveEvent;
import org.battleplugins.arena.module.ArenaModule;
import org.battleplugins.arena.module.ArenaModuleInitializer;
import org.battleplugins.arena.options.ArenaOptionType;
import org.battleplugins.arena.options.types.BooleanArenaOption;
import org.battleplugins.arena.team.ArenaTeam;
import org.battleplugins.arena.team.ArenaTeams;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.scoreboard.Team;

/**
* A module that adds team colors to a player's name.
*/
@ArenaModule(id = TeamColors.ID, name = "Team Colors", description = "Adds player team colors to their name.", authors = "BattlePlugins")
public class TeamColors implements ArenaModuleInitializer {
public static final String ID = "team-colors";
public static final ArenaOptionType<BooleanArenaOption> TEAM_PREFIXES = ArenaOptionType.create("team-prefixes", BooleanArenaOption::new);

@EventHandler
public void onJoin(ArenaJoinEvent event) {
if (!event.getArena().isModuleEnabled(ID)) {
return;
}

this.post(5, () -> {
for (ArenaTeam team : event.getCompetition().getTeamManager().getTeams()) {
// Register a new Bukkit team for each team in the competition
Team bukkitTeam = event.getPlayer().getScoreboard().getTeam("ba-" + team.getName());
if (bukkitTeam != null) {
bukkitTeam = event.getPlayer().getScoreboard().registerNewTeam("ba-" + team.getName());
bukkitTeam.displayName(team.getFormattedName());
bukkitTeam.color(NamedTextColor.nearestTo(team.getTextColor()));
if (showTeamPrefixes(event.getCompetition(), team)) {
bukkitTeam.prefix(Component.text("[" + team.getName() + "] ", team.getTextColor()));
}
}

// If players are already on the team, add them to the Bukkit team
for (ArenaPlayer teamPlayer : event.getCompetition().getTeamManager().getPlayersOnTeam(team)) {
bukkitTeam.addPlayer(teamPlayer.getPlayer());
}
}
});
}

@EventHandler
public void onPhaseStart(ArenaPhaseStartEvent event) {
if (!event.getArena().isModuleEnabled(ID)) {
return;
}

this.post(5, () -> {
// Scoreboards may change when phases change, so update
// team colors in player scoreboards when this happens
if (event.getCompetition() instanceof LiveCompetition<?> liveCompetition) {
for (ArenaPlayer arenaPlayer : liveCompetition.getPlayers()) {
Player player = arenaPlayer.getPlayer();
for (ArenaTeam team : liveCompetition.getTeamManager().getTeams()) {
Team bukkitTeam = player.getScoreboard().getTeam("ba-" + team.getName());
if (bukkitTeam == null) {
bukkitTeam = player.getScoreboard().registerNewTeam("ba-" + team.getName());
bukkitTeam.displayName(team.getFormattedName());
bukkitTeam.color(NamedTextColor.nearestTo(team.getTextColor()));
if (showTeamPrefixes(liveCompetition, team)) {
bukkitTeam.prefix(Component.text("[" + team.getName() + "] ", team.getTextColor()));
}
}

for (ArenaPlayer teamPlayer : arenaPlayer.getCompetition().getTeamManager().getPlayersOnTeam(team)) {
bukkitTeam.addPlayer(teamPlayer.getPlayer());
}
}
}
}
});
}

@EventHandler
public void onLeave(ArenaLeaveEvent event) {
if (!event.getArena().isModuleEnabled(ID)) {
return;
}

this.post(5, () -> {
if (event.getArenaPlayer().getTeam() != null) {
this.leaveTeam(event.getPlayer(), event.getCompetition(), event.getArenaPlayer().getTeam());
}

// Remove all teams for the player
for (ArenaTeam team : event.getCompetition().getTeamManager().getTeams()) {
Team bukkitTeam = event.getPlayer().getScoreboard().getTeam("ba-" + team.getName());
if (bukkitTeam != null) {
bukkitTeam.unregister();
}
}
});
}

@EventHandler
public void onTeamJoin(ArenaTeamJoinEvent event) {
if (!event.getArena().isModuleEnabled(ID)) {
return;
}

this.post(5, () -> this.joinTeam(event.getPlayer(), event.getCompetition(), event.getTeam()));
}

@EventHandler
public void onTeamLeave(ArenaTeamLeaveEvent event) {
if (!event.getArena().isModuleEnabled(ID)) {
return;
}

this.post(5, () -> this.leaveTeam(event.getPlayer(), event.getCompetition(), event.getTeam()));
}

private void joinTeam(Player player, LiveCompetition<?> competition, ArenaTeam arenaTeam) {
for (ArenaPlayer arenaPlayer : competition.getPlayers()) {
Player competitionPlayer = arenaPlayer.getPlayer();

Team team = competitionPlayer.getScoreboard().getTeam("ba-" + arenaTeam.getName());
if (team == null) {
BattleArena.getInstance().warn("Team {} does not have a Bukkit team registered for {}!", arenaTeam.getName(), player.getName());
continue;
}

team.addPlayer(player);
}
}

private void leaveTeam(Player player, LiveCompetition<?> competition, ArenaTeam arenaTeam) {
for (ArenaPlayer arenaPlayer : competition.getPlayers()) {
Player competitionPlayer = arenaPlayer.getPlayer();
Team team = competitionPlayer.getScoreboard().getTeam("ba-" + arenaTeam.getName());
if (team != null) {
team.removePlayer(player);
}
}
}

private void post(int ticks, Runnable runnable) {
Bukkit.getScheduler().runTaskLater(BattleArena.getInstance(), runnable, ticks);
}

private static boolean showTeamPrefixes(LiveCompetition<?> competition, ArenaTeam team) {
if (team == ArenaTeams.DEFAULT) {
return false;
}

return competition.option(TEAM_PREFIXES)
.map(BooleanArenaOption::isEnabled)
.orElse(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void removeCompetition(Arena arena, Competition<?> competition) {
liveCompetition.getPhaseManager().end(true);
} else {
// No victory phase - just forcefully kick every player
for (ArenaPlayer player : liveCompetition.getPlayers()) {
for (ArenaPlayer player : Set.copyOf(liveCompetition.getPlayers())) {
liveCompetition.leave(player, ArenaLeaveEvent.Cause.SHUTDOWN);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.battleplugins.arena.options.types.BooleanArenaOption;
import org.battleplugins.arena.options.types.EnumArenaOption;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
Expand Down Expand Up @@ -81,53 +82,64 @@ public void onPlayerDeath(PlayerDeathEvent event) {

@ArenaEventHandler(priority = EventPriority.LOWEST)
public void onEntityDamage(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player damager) {
if (!(event.getEntity() instanceof Player damaged)) {
DamageOption damageOption = this.competition.option(ArenaOptionType.DAMAGE_ENTITIES)
.map(EnumArenaOption::getOption)
.orElse(DamageOption.ALWAYS);

if (damageOption == DamageOption.NEVER) {
event.setCancelled(true);
}
Player damager;
if (event.getDamager() instanceof Player eventDamager) {
damager = eventDamager;
} else if (event.getDamager() instanceof Projectile projectile) {
if (projectile.getShooter() instanceof Player shooter) {
damager = shooter;
} else {
// Player damage checking is slightly more complicated
DamageOption damageOption = this.competition.option(ArenaOptionType.DAMAGE_PLAYERS)
.map(EnumArenaOption::getOption)
.orElse(DamageOption.ALWAYS);

// If the damage option is always, then assume damage is enabled in
// any case and just return here
if (damageOption == DamageOption.ALWAYS) {
return;
}
return;
}
} else {
return;
}

ArenaPlayer damagerPlayer = ArenaPlayer.getArenaPlayer(damager);
ArenaPlayer damagedPlayer = ArenaPlayer.getArenaPlayer(damaged);
if (!(event.getEntity() instanceof Player damaged)) {
DamageOption damageOption = this.competition.option(ArenaOptionType.DAMAGE_ENTITIES)
.map(EnumArenaOption::getOption)
.orElse(DamageOption.ALWAYS);

// Ensure that both players exist and are in an arena
if ((damagerPlayer == null && damagedPlayer != null) || (damagerPlayer != null && damagedPlayer == null)) {
return;
}
if (damageOption == DamageOption.NEVER) {
event.setCancelled(true);
}
} else {
// Player damage checking is slightly more complicated
DamageOption damageOption = this.competition.option(ArenaOptionType.DAMAGE_PLAYERS)
.map(EnumArenaOption::getOption)
.orElse(DamageOption.ALWAYS);

// If the damage option is always, then assume damage is enabled in
// any case and just return here
if (damageOption == DamageOption.ALWAYS) {
return;
}

// Check to see if players are in the same arena
if (damagerPlayer != null && !damagerPlayer.getCompetition().equals(damagedPlayer.getCompetition())) {
return;
}
ArenaPlayer damagerPlayer = ArenaPlayer.getArenaPlayer(damager);
ArenaPlayer damagedPlayer = ArenaPlayer.getArenaPlayer(damaged);

// If the damage option is never, then cancel the event
if (damageOption == DamageOption.NEVER) {
event.setCancelled(true);
return;
}
// Ensure that both players exist and are in an arena
if ((damagerPlayer == null && damagedPlayer != null) || (damagerPlayer != null && damagedPlayer == null)) {
return;
}

// Check to see if players are in the same arena
if (damagerPlayer != null && !damagerPlayer.getCompetition().equals(damagedPlayer.getCompetition())) {
return;
}

// If the damage option is never, then cancel the event
if (damageOption == DamageOption.NEVER) {
event.setCancelled(true);
return;
}

// Cancel the event if the damage option is other team and the
// players are on the same team
if (damageOption == DamageOption.OTHER_TEAM && damagerPlayer != null) {
if (damagerPlayer.getTeam() != null && damagedPlayer.getTeam() != null) {
if (!damagerPlayer.getTeam().isHostileTo(damagedPlayer.getTeam())) {
event.setCancelled(true);
}
// Cancel the event if the damage option is other team and the
// players are on the same team
if (damageOption == DamageOption.OTHER_TEAM && damagerPlayer != null) {
if (damagerPlayer.getTeam() != null && damagedPlayer.getTeam() != null) {
if (!damagerPlayer.getTeam().isHostileTo(damagedPlayer.getTeam())) {
event.setCancelled(true);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public Duration getTimeRemaining() {
public Resolver resolve() {
return super.resolve().toBuilder()
.define(ResolverKeys.TIME_REMAINING, ResolverProvider.simple(this.getTimeRemaining(), Util::toTimeString))
.define(ResolverKeys.TIME_REMAINING_SHORT, ResolverProvider.simple(this.getTimeRemaining(), Util::toTimeStringShort))
.build();
}
}
Loading

0 comments on commit a2df3be

Please sign in to comment.