forked from alkarinv/BattleArena
-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add duels support and fix an issue with third party chat plugins
- Loading branch information
Showing
13 changed files
with
299 additions
and
12 deletions.
There are no files selected for viewing
Empty file.
129 changes: 129 additions & 0 deletions
129
module/duels/src/main/java/org/battleplugins/arena/module/duels/Duels.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package org.battleplugins.arena.module.duels; | ||
|
||
import org.battleplugins.arena.Arena; | ||
import org.battleplugins.arena.competition.Competition; | ||
import org.battleplugins.arena.competition.JoinResult; | ||
import org.battleplugins.arena.competition.LiveCompetition; | ||
import org.battleplugins.arena.competition.PlayerRole; | ||
import org.battleplugins.arena.competition.map.LiveCompetitionMap; | ||
import org.battleplugins.arena.competition.map.MapType; | ||
import org.battleplugins.arena.competition.phase.CompetitionPhaseType; | ||
import org.battleplugins.arena.event.arena.ArenaCreateExecutorEvent; | ||
import org.battleplugins.arena.event.player.ArenaPreJoinEvent; | ||
import org.battleplugins.arena.messages.Messages; | ||
import org.battleplugins.arena.module.ArenaModule; | ||
import org.battleplugins.arena.module.ArenaModuleInitializer; | ||
import org.battleplugins.arena.team.ArenaTeam; | ||
import org.bukkit.Bukkit; | ||
import org.bukkit.entity.Player; | ||
import org.bukkit.event.EventHandler; | ||
import org.bukkit.event.EventPriority; | ||
import org.bukkit.event.player.PlayerQuitEvent; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.UUID; | ||
|
||
/** | ||
* A module that adds duels to BattleArena. | ||
*/ | ||
@ArenaModule(id = Duels.ID, name = "Duels", description = "Adds duels to BattleArena.", authors = "BattlePlugins") | ||
public class Duels implements ArenaModuleInitializer { | ||
public static final String ID = "duels"; | ||
public static final JoinResult PENDING_REQUEST = new JoinResult(false, DuelsMessages.PENDING_DUEL_REQUEST); | ||
|
||
private final Map<UUID, UUID> duelRequests = new HashMap<>(); | ||
|
||
@EventHandler | ||
public void onCreateExecutor(ArenaCreateExecutorEvent event) { | ||
if (!event.getArena().isModuleEnabled(ID)) { | ||
return; | ||
} | ||
|
||
event.registerSubExecutor(new DuelsExecutor(this, event.getArena())); | ||
} | ||
|
||
@EventHandler | ||
public void onPlayerQuit(PlayerQuitEvent event) { | ||
UUID requested = this.duelRequests.remove(event.getPlayer().getUniqueId()); | ||
Player requestedPlayer = Bukkit.getPlayer(requested); | ||
if (requestedPlayer != null) { | ||
DuelsMessages.DUEL_REQUESTED_CANCELLED_QUIT.send(requestedPlayer, event.getPlayer().getName()); | ||
} | ||
} | ||
|
||
@EventHandler(priority = EventPriority.HIGHEST) | ||
public void onPreJoin(ArenaPreJoinEvent event) { | ||
if (this.duelRequests.containsKey(event.getPlayer().getUniqueId())) { | ||
event.setResult(PENDING_REQUEST); | ||
} | ||
} | ||
|
||
public Map<UUID, UUID> getDuelRequests() { | ||
return Map.copyOf(this.duelRequests); | ||
} | ||
|
||
public void addDuelRequest(UUID sender, UUID receiver) { | ||
this.duelRequests.put(sender, receiver); | ||
} | ||
|
||
public void removeDuelRequest(UUID sender) { | ||
this.duelRequests.remove(sender); | ||
} | ||
|
||
public void acceptDuel(Arena arena, Player player, Player target) { | ||
LiveCompetition<?> competition = findOrJoinCompetition(arena); | ||
if (competition == null) { | ||
Messages.NO_OPEN_ARENAS.send(player); | ||
Messages.NO_OPEN_ARENAS.send(target); | ||
return; | ||
} | ||
|
||
// Non-team game - just join regularly and let game calculate team. Winner will be | ||
// determined by the individual player who wins | ||
if (arena.getTeams().isNonTeamGame()) { | ||
competition.join(player, PlayerRole.PLAYING); | ||
competition.join(target, PlayerRole.PLAYING); | ||
} else { | ||
ArenaTeam team1 = competition.getTeamManager().getTeams().iterator().next(); | ||
ArenaTeam team2 = competition.getTeamManager().getTeams().iterator().next(); | ||
|
||
competition.join(player, PlayerRole.PLAYING, team1); | ||
competition.join(target, PlayerRole.PLAYING, team2); | ||
} | ||
|
||
// Force the game into the in-game state | ||
competition.getPhaseManager().setPhase(CompetitionPhaseType.INGAME); | ||
} | ||
|
||
private LiveCompetition<?> findOrJoinCompetition(Arena arena) { | ||
List<Competition<?>> openCompetitions = arena.getPlugin().getCompetitions(arena) | ||
.stream() | ||
.filter(competition -> competition instanceof LiveCompetition<?> liveCompetition | ||
&& liveCompetition.getPhaseManager().getCurrentPhase().canJoin() | ||
&& liveCompetition.getPlayers().isEmpty() | ||
) | ||
.toList(); | ||
|
||
// Ensure we have found an open competition | ||
if (openCompetitions.isEmpty()) { | ||
List<LiveCompetitionMap> dynamicMaps = arena.getPlugin().getMaps(arena) | ||
.stream() | ||
.filter(map -> map.getType() == MapType.DYNAMIC) | ||
.toList(); | ||
|
||
if (dynamicMaps.isEmpty()) { | ||
return null; | ||
} | ||
|
||
LiveCompetitionMap map = dynamicMaps.iterator().next(); | ||
|
||
LiveCompetition<?> competition = map.createDynamicCompetition(arena); | ||
arena.getPlugin().addCompetition(arena, competition); | ||
return competition; | ||
} else { | ||
return (LiveCompetition<?>) openCompetitions.iterator().next(); | ||
} | ||
} | ||
} |
133 changes: 133 additions & 0 deletions
133
module/duels/src/main/java/org/battleplugins/arena/module/duels/DuelsExecutor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package org.battleplugins.arena.module.duels; | ||
|
||
import org.battleplugins.arena.Arena; | ||
import org.battleplugins.arena.ArenaPlayer; | ||
import org.battleplugins.arena.BattleArena; | ||
import org.battleplugins.arena.command.ArenaCommand; | ||
import org.battleplugins.arena.command.SubCommandExecutor; | ||
import org.battleplugins.arena.messages.Messages; | ||
import org.bukkit.Bukkit; | ||
import org.bukkit.entity.Player; | ||
|
||
import java.util.Locale; | ||
import java.util.UUID; | ||
|
||
public class DuelsExecutor implements SubCommandExecutor { | ||
private final Duels module; | ||
private final Arena arena; | ||
private final String parentCommand; | ||
|
||
public DuelsExecutor(Duels module, Arena arena) { | ||
this.module = module; | ||
this.arena = arena; | ||
this.parentCommand = arena.getName().toLowerCase(Locale.ROOT); | ||
} | ||
|
||
@ArenaCommand(commands = "duel", description = "Duel another player.", permissionNode = "duel") | ||
public void duel(Player player, Player target) { | ||
if (player.equals(target)) { | ||
DuelsMessages.CANNOT_DUEL_SELF.send(player); | ||
return; | ||
} | ||
|
||
ArenaPlayer arenaPlayer = ArenaPlayer.getArenaPlayer(player); | ||
if (arenaPlayer != null) { | ||
Messages.ALREADY_IN_ARENA.send(player); | ||
return; | ||
} | ||
|
||
ArenaPlayer targetPlayer = ArenaPlayer.getArenaPlayer(target); | ||
if (targetPlayer != null) { | ||
Messages.ALREADY_IN_ARENA.send(player); | ||
return; | ||
} | ||
|
||
if (this.module.getDuelRequests().containsKey(player.getUniqueId())) { | ||
DuelsMessages.DUEL_REQUEST_ALREADY_SENT.send(player, this.parentCommand); | ||
return; | ||
} | ||
|
||
DuelsMessages.DUEL_REQUEST_SENT.send(player, target.getName()); | ||
DuelsMessages.DUEL_REQUEST_RECEIVED.send( | ||
target, | ||
player.getName(), | ||
this.parentCommand, | ||
player.getName(), | ||
this.parentCommand, | ||
player.getName() | ||
); | ||
|
||
this.module.addDuelRequest(player.getUniqueId(), target.getUniqueId()); | ||
} | ||
|
||
@ArenaCommand(commands = "duel", subCommands = "accept", description = "Accept a duel request.", permissionNode = "duel.accept") | ||
public void acceptDuel(Player player, Player target) { | ||
ArenaPlayer arenaPlayer = ArenaPlayer.getArenaPlayer(player); | ||
if (arenaPlayer != null) { | ||
Messages.ALREADY_IN_ARENA.send(player); | ||
return; | ||
} | ||
|
||
UUID requestedId = this.module.getDuelRequests().get(target.getUniqueId()); | ||
if (requestedId == null) { | ||
DuelsMessages.NO_DUEL_REQUESTS.send(player); | ||
return; | ||
} | ||
|
||
if (!requestedId.equals(player.getUniqueId())) { | ||
DuelsMessages.USER_DID_NOT_REQUEST.send(player, target.getName()); | ||
return; | ||
} | ||
|
||
DuelsMessages.DUEL_REQUEST_ACCEPTED.send(player, target.getName()); | ||
DuelsMessages.ACCEPTED_DUEL_REQUEST.send(target, player.getName()); | ||
|
||
this.module.removeDuelRequest(target.getUniqueId()); | ||
|
||
Bukkit.getScheduler().runTaskLater(BattleArena.getInstance(), () -> { | ||
this.module.acceptDuel(this.arena, player, target); | ||
}, 100); | ||
} | ||
|
||
@ArenaCommand(commands = "duel", subCommands = "deny", description = "Deny a duel request.", permissionNode = "duel.deny") | ||
public void denyDuel(Player player, Player target) { | ||
UUID requestedId = this.module.getDuelRequests().get(target.getUniqueId()); | ||
if (requestedId == null) { | ||
DuelsMessages.NO_DUEL_REQUESTS.send(player); | ||
return; | ||
} | ||
|
||
if (!requestedId.equals(player.getUniqueId())) { | ||
DuelsMessages.USER_DID_NOT_REQUEST.send(player, target.getName()); | ||
return; | ||
} | ||
|
||
DuelsMessages.DUEL_REQUEST_DENIED.send(player, target.getName()); | ||
DuelsMessages.DENIED_DUEL_REQUEST.send(target, player.getName()); | ||
|
||
this.module.removeDuelRequest(target.getUniqueId()); | ||
} | ||
|
||
@ArenaCommand(commands = "duel", subCommands = "cancel", description = "Cancel a duel request.", permissionNode = "duel.cancel") | ||
public void cancelDuel(Player player) { | ||
if (!this.module.getDuelRequests().containsKey(player.getUniqueId())) { | ||
DuelsMessages.NO_DUEL_REQUESTS.send(player); | ||
return; | ||
} | ||
|
||
UUID targetId = this.module.getDuelRequests().get(player.getUniqueId()); | ||
Player target = Bukkit.getServer().getPlayer(targetId); | ||
if (target == null) { | ||
// Shouldn't get here but just incase | ||
this.module.removeDuelRequest(player.getUniqueId()); | ||
|
||
DuelsMessages.NO_DUEL_REQUESTS.send(player); | ||
return; | ||
} | ||
|
||
DuelsMessages.DUEL_REQUEST_CANCELLED.send(player, target.getName()); | ||
DuelsMessages.CANCELLED_DUEL_REQUEST.send(target, player.getName()); | ||
|
||
this.module.removeDuelRequest(player.getUniqueId()); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
module/duels/src/main/java/org/battleplugins/arena/module/duels/DuelsMessages.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.battleplugins.arena.module.duels; | ||
|
||
import org.battleplugins.arena.messages.Message; | ||
import org.battleplugins.arena.messages.Messages; | ||
|
||
public final class DuelsMessages { | ||
public static final Message CANNOT_DUEL_SELF = Messages.error("duel-cannot-duel-self", "You cannot duel yourself!"); | ||
public static final Message DUEL_REQUEST_SENT = Messages.info("duel-request-sent", "Duel request sent to <secondary>{}</secondary>!"); | ||
public static final Message DUEL_REQUEST_RECEIVED = Messages.info("duel-request-received", "You have received a duel request from <secondary>{}</secondary>! Type <secondary>/{} duel accept {}</secondary> to accept or <secondary>/{} duel deny {}</secondary> to deny."); | ||
public static final Message DUEL_REQUEST_ALREADY_SENT = Messages.error("duel-request-already-sent", "You have already have an outgoing duel request! Type <secondary>/{} duel cancel</secondary> to cancel."); | ||
public static final Message NO_DUEL_REQUESTS = Messages.error("duel-no-requests", "You have no duel requests!"); | ||
public static final Message USER_DID_NOT_REQUEST = Messages.error("duel-user-did-not-request", "<secondary>{}</secondary> did not request a duel with you! You can only accept requests from the user who sent it."); | ||
public static final Message DUEL_REQUEST_DENIED = Messages.info("duel-request-denied", "You have denied the duel request from <secondary>{}</secondary>!"); | ||
public static final Message DENIED_DUEL_REQUEST = Messages.error("duel-denied-request", "<secondary>{}</secondary> has denied your duel request!"); | ||
public static final Message DUEL_REQUEST_CANCELLED = Messages.info("duel-request-cancelled", "You have cancelled your duel request to <secondary>{}</secondary>!"); | ||
public static final Message CANCELLED_DUEL_REQUEST = Messages.error("duel-cancelled-request", "<secondary>{}</secondary> has cancelled their duel request!"); | ||
public static final Message DUEL_REQUESTED_CANCELLED_QUIT = Messages.info("duel-request-cancelled-quit", "Your duel request from <secondary>{}</secondary> has been cancelled as they have left the server."); | ||
public static final Message DUEL_REQUEST_ACCEPTED = Messages.info("duel-request-accepted", "You have accepted the duel request from <secondary>{}</secondary>! The duel will commence in <secondary>5 seconds</secondary>!"); | ||
public static final Message ACCEPTED_DUEL_REQUEST = Messages.info("duel-accepted-request", "<secondary>{}</secondary> has accepted your duel request! The duel will commence in <secondary>5 seconds</secondary>!"); | ||
public static final Message PENDING_DUEL_REQUEST = Messages.error("duel-pending-request", "You have a pending outgoing duel request! Type <secondary>/arena duel cancel</secondary> to cancel."); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.