001package fr.aumgn.dac2.game.colonnisation; 002 003import java.util.ArrayList; 004import java.util.Arrays; 005import java.util.List; 006import java.util.Map; 007import java.util.Map.Entry; 008 009import org.bukkit.World; 010import org.bukkit.command.CommandSender; 011import org.bukkit.entity.Player; 012 013import fr.aumgn.bukkitutils.localization.PluginMessages; 014import fr.aumgn.bukkitutils.playerref.PlayerRef; 015import fr.aumgn.bukkitutils.playerref.map.PlayersRefHashMap; 016import fr.aumgn.bukkitutils.playerref.map.PlayersRefMap; 017import fr.aumgn.bukkitutils.timer.Timer; 018import fr.aumgn.dac2.DAC; 019import fr.aumgn.dac2.arena.regions.Pool; 020import fr.aumgn.dac2.game.AbstractGame; 021import fr.aumgn.dac2.game.GameParty; 022import fr.aumgn.dac2.game.GameTimer; 023import fr.aumgn.dac2.game.start.GameStartData; 024import fr.aumgn.dac2.game.start.PlayerStartData; 025import fr.aumgn.dac2.shape.column.Column; 026import fr.aumgn.dac2.shape.column.ColumnPattern; 027import fr.aumgn.dac2.shape.column.GlassyPattern; 028 029public class Colonnisation extends AbstractGame { 030 031 private final GameParty<ColonnPlayer> party; 032 private final PlayersRefMap<ColonnPlayer> playersMap; 033 034 private final Runnable turnTimedOut = new Runnable() { 035 @Override 036 public void run() { 037 turnTimedOut(); 038 } 039 }; 040 041 private boolean finished; 042 private Timer timer; 043 private int setupTurns; 044 045 public Colonnisation(DAC dac, GameStartData data) { 046 super(dac, data); 047 048 Map<PlayerRef, ? extends PlayerStartData> playersData = 049 data.getPlayersData(); 050 List<ColonnPlayer> list = 051 new ArrayList<ColonnPlayer>(playersData.size()); 052 playersMap = new PlayersRefHashMap<ColonnPlayer>(); 053 054 for (Entry<PlayerRef, ? extends PlayerStartData> entry : 055 playersData.entrySet()) { 056 PlayerRef playerId = entry.getKey(); 057 ColonnPlayer player = new ColonnPlayer(playerId, 058 playersData.get(playerId)); 059 list.add(player); 060 playersMap.put(playerId, player); 061 } 062 party = new GameParty<ColonnPlayer>(this, ColonnPlayer.class, list); 063 064 finished = false; 065 } 066 067 @Override 068 public void start() { 069 resetPoolOnStart(); 070 071 double size = arena.getPool().size2D(); 072 double setupColumns = size * dac.getConfig().getColonnisationRatio(); 073 setupTurns = (int) Math.ceil(setupColumns / party.size()); 074 075 send("colonnisation.start"); 076 send("colonnisation.playerslist"); 077 for (ColonnPlayer player : party.iterable()) { 078 send("colonnisation.start.playerentry", player.getIndex() + 1, 079 player.getDisplayName()); 080 } 081 send("colonnisation.setup.turns", setupTurns); 082 nextTurn(); 083 } 084 085 @Override 086 public void onNewTurn() { 087 setupTurns--; 088 if (setupTurns == 0) { 089 send("colonnisation.setup.finished"); 090 send("colonnisation.enjoy"); 091 } 092 } 093 094 private void nextTurn() { 095 ColonnPlayer player = party.nextTurn(); 096 097 if (!player.isOnline()) { 098 send("colonnisation.playerturn.notconnected", 099 player.getDisplayName()); 100 removePlayer(player); 101 if (!finished) { 102 nextTurn(); 103 } 104 return; 105 } 106 107 if (timer != null) { 108 timer.cancel(); 109 } 110 timer = new GameTimer(dac, this, turnTimedOut); 111 timer.start(); 112 113 send("colonnisation.playerturn", player.getDisplayName()); 114 tpBeforeJump(player); 115 } 116 117 private void turnTimedOut() { 118 ColonnPlayer player = party.getCurrent(); 119 removePlayer(player); 120 if (!finished) { 121 nextTurn(); 122 } 123 } 124 125 private void removePlayer(ColonnPlayer player) { 126 party.removePlayer(player); 127 playersMap.remove(player.playerId); 128 spectators.add(player.playerId); 129 if (party.size() < 2) { 130 dac.getStages().stop(this); 131 } 132 } 133 134 @Override 135 public void stop(boolean force) { 136 finished = true; 137 resetPoolOnEnd(); 138 if (timer != null) { 139 timer.cancel(); 140 } 141 142 if (force) { 143 send("colonnisation.stopped"); 144 } else { 145 send("colonnisation.finished"); 146 } 147 148 ColonnPlayer[] ranking = party.iterable().clone(); 149 Arrays.sort(ranking); 150 151 int index = ranking.length - 1; 152 send("colonnisation.winner", ranking[index].getDisplayName(), 153 ranking[index].getScore()); 154 index--; 155 for (; index >= 0; index--) { 156 send("colonnisation.ranking", ranking.length - index, 157 ranking[index].getDisplayName(), ranking[index].getScore()); 158 } 159 } 160 161 @Override 162 public boolean contains(Player player) { 163 return playersMap.containsKey(player); 164 } 165 166 @Override 167 public void sendMessage(String message) { 168 for (ColonnPlayer player : party.iterable()) { 169 player.sendMessage(message); 170 } 171 sendSpectators(message); 172 } 173 174 @Override 175 public boolean isPlayerTurn(Player player) { 176 ColonnPlayer gamePlayer = playersMap.get(player); 177 return gamePlayer != null && party.isTurn(gamePlayer); 178 } 179 180 @Override 181 public void onJumpSuccess(Player player) { 182 ColonnPlayer gamePlayer = playersMap.get(player); 183 World world = arena.getWorld(); 184 Pool pool = arena.getPool(); 185 186 Column column = pool.getColumn(player); 187 ColumnPattern pattern; 188 if (setupTurns > 0) { 189 pattern = dac.getConfig().getNeutralPattern(); 190 send("colonnisation.setup.success", gamePlayer.getDisplayName()); 191 } else { 192 pattern = gamePlayer.getColumnPattern(); 193 boolean isADAC = column.isADAC(world); 194 if (isADAC) { 195 gamePlayer.incrementMultiplier(); 196 pattern = new GlassyPattern(pattern); 197 } 198 199 PoolVisitor visitor = new PoolVisitor(world, pool, 200 gamePlayer.getColor()); 201 int points = visitor.visit(column.getPos()); 202 points *= gamePlayer.getMultiplier(); 203 gamePlayer.addPoints(points); 204 205 if (isADAC) { 206 send("colonnisation.multiplier.increment", 207 gamePlayer.getMultiplier()); 208 } 209 send("colonnisation.jump.success", gamePlayer.getDisplayName(), 210 points, gamePlayer.getScore()); 211 } 212 213 column.set(world, pattern); 214 tpAfterJumpSuccess(gamePlayer, column); 215 if (pool.isFilled(world)) { 216 dac.getStages().stop(this); 217 } else { 218 nextTurn(); 219 } 220 } 221 222 @Override 223 public void onJumpFail(Player player) { 224 ColonnPlayer gamePlayer = playersMap.get(player); 225 226 send("colonnisation.jump.fail", gamePlayer.getDisplayName()); 227 if (gamePlayer.getMultiplier() > 1) { 228 gamePlayer.resetMultiplier(); 229 send("colonnisation.multiplier.reset"); 230 } 231 232 tpAfterJumpFail(gamePlayer); 233 nextTurn(); 234 } 235 236 @Override 237 public void onQuit(Player player) { 238 ColonnPlayer gamePlayer = playersMap.get(player); 239 removePlayer(gamePlayer); 240 send("colonnisation.player.quit", gamePlayer.getDisplayName(), 241 gamePlayer.getScore()); 242 if (!finished) { 243 nextTurn(); 244 } 245 } 246 247 @Override 248 public void list(CommandSender sender) { 249 PluginMessages messages = dac.getMessages(); 250 251 sender.sendMessage(messages.get("colonnisation.playerslist")); 252 for (ColonnPlayer player : party.iterable()) { 253 sender.sendMessage(messages.get("colonnisation.playerentry", 254 player.getIndex(), player.getDisplayName(), 255 player.getScore())); 256 } 257 } 258}