001package fr.aumgn.dac2.game; 002 003import org.bukkit.Bukkit; 004import org.bukkit.entity.Player; 005import org.bukkit.event.Listener; 006import org.bukkit.event.player.PlayerMoveEvent; 007 008import fr.aumgn.bukkitutils.playerref.set.PlayersRefHashSet; 009import fr.aumgn.bukkitutils.playerref.set.PlayersRefSet; 010import fr.aumgn.dac2.DAC; 011import fr.aumgn.dac2.arena.Arena; 012import fr.aumgn.dac2.game.start.GameStartData; 013import fr.aumgn.dac2.shape.column.Column; 014 015/** 016 * Common implementations of most game mode. 017 */ 018public abstract class AbstractGame implements Game { 019 020 protected final DAC dac; 021 protected final Arena arena; 022 protected final Listener listener; 023 protected final PlayersRefSet spectators; 024 025 public AbstractGame(DAC dac, GameStartData data) { 026 this.dac = dac; 027 this.arena = data.getArena(); 028 this.listener = new GameListener(this); 029 this.spectators = new PlayersRefHashSet(); 030 spectators.addAll(data.getSpectators()); 031 } 032 033 @Override 034 public Arena getArena() { 035 return arena; 036 } 037 038 @Override 039 public Listener[] getListeners() { 040 return new Listener[] { listener }; 041 } 042 043 /** 044 * Send a message which is recorded in the main PluginMessages instance. 045 */ 046 protected void send(String key, Object... arguments) { 047 sendMessage(dac.getMessages().get(key, arguments)); 048 } 049 050 @Override 051 public boolean isSpectator(Player player) { 052 return spectators.contains(player); 053 } 054 055 @Override 056 public void addSpectator(Player player) { 057 spectators.add(player); 058 } 059 060 @Override 061 public void removeSpectator(Player player) { 062 spectators.remove(player); 063 } 064 065 @Override 066 public void onNewTurn() { 067 } 068 069 /** 070 * Check if it's the given player turn. 071 * 072 * This is used by {@link GameListener} to check if events need to be 073 * processed. So this method should be optimized as much as possible 074 * because some events (like {@link PlayerMoveEvent}) are heavy. 075 */ 076 public abstract boolean isPlayerTurn(Player player); 077 078 /** 079 * Callback called when a player succeed. 080 */ 081 public abstract void onJumpSuccess(Player player); 082 083 /** 084 * Callback called when a player failed. 085 */ 086 public abstract void onJumpFail(Player player); 087 088 /** 089 * Sends a message to this game's spectators by prefixing 090 * the message with the arena's name as specified in the config. 091 */ 092 protected void sendSpectators(String message) { 093 String spectatorMessage = dac.getConfig().getSpectatorsMsg() 094 .format(new String[] { arena.getName(), message }); 095 for (Player spectator : spectators.players()) { 096 spectator.sendMessage(spectatorMessage); 097 } 098 } 099 100 /** 101 * Resets the pool if configured to do so on game start. 102 */ 103 protected void resetPoolOnStart() { 104 if (dac.getConfig().getResetOnStart()) { 105 arena.getPool().reset(arena.getWorld()); 106 } 107 } 108 109 /** 110 * Resets the pool if configured to do so on game end. 111 */ 112 protected void resetPoolOnEnd() { 113 if (dac.getConfig().getResetOnEnd()) { 114 arena.getPool().reset(arena.getWorld()); 115 } 116 } 117 118 /** 119 * Teleport the player if configured to do so on player's turn. 120 */ 121 protected void tpBeforeJump(GamePlayer player) { 122 if (dac.getConfig().getTpBeforeJump()) { 123 player.teleport(arena.getDiving().toLocation(arena.getWorld())); 124 } 125 } 126 127 /** 128 * Teleport the player if configured to do so after player's success. 129 */ 130 protected void tpAfterJumpSuccess(final GamePlayer player, Column column) { 131 int delay = dac.getConfig().getTpAfterJumpSuccessDelay(); 132 if (delay == 0) { 133 player.tpToStart(); 134 return; 135 } 136 137 player.teleport(arena.getWorld(), column.getTop().addY(1)); 138 if (delay > 0) { 139 Bukkit.getScheduler().scheduleSyncDelayedTask(dac.getPlugin(), 140 player.delayedTpToStart(), delay); 141 } 142 } 143 144 /** 145 * Teleport the player if configured to do so after player's failed jump. 146 */ 147 protected void tpAfterJumpFail(final GamePlayer player) { 148 int delay = dac.getConfig().getTpAfterJumpFailDelay(); 149 if (delay == 0) { 150 player.tpToStart(); 151 } else if (delay > 0) { 152 Bukkit.getScheduler().scheduleSyncDelayedTask(dac.getPlugin(), 153 player.delayedTpToStart(), delay); 154 } 155 } 156}