This repository has been archived by the owner on Mar 30, 2018. It is now read-only.
/
GameWithTeams.java
316 lines (283 loc) · 11.7 KB
/
GameWithTeams.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/**
* This file is part of the SimpleSpleef bukkit plugin.
* Copyright (C) 2011 Maximilian Kalus
* See http://dev.bukkit.org/server-mods/simple-spleef/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
package de.beimax.simplespleef.game;
import java.util.LinkedList;
import java.util.Random;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import de.beimax.simplespleef.SimpleSpleef;
import de.beimax.simplespleef.gamehelpers.LocationHelper;
import de.beimax.simplespleef.gamehelpers.MaterialHelper;
/**
* @author mkalus
*
*/
public class GameWithTeams extends GameStandard {
/**
* Constructor
* @param name
*/
public GameWithTeams(String name) {
super(name);
}
@Override
public String getType() {
return "randomteams";
}
@Override
public String getNumberOfPlayers() {
// if in progress - tell about teams
if (isInProgress()) {
// no spleefers - return empty string
if (spleefers == null || spleefers.size() == 0) return "";
int max = spleefers.size();
return new StringBuilder().append(ChatColor.WHITE).append('(')
.append(ChatColor.BLUE).append(spleefers.inGame(Spleefer.TEAM_BLUE))
.append(ChatColor.WHITE).append(": ")
.append(ChatColor.RED).append(spleefers.inGame(Spleefer.TEAM_RED))
.append(ChatColor.WHITE).append('/')
.append((max>0?max:'-')).append(')').toString();
} else return super.getNumberOfPlayers();
}
@Override
public String getListOfSpleefers() {
// no spleefers - return null
if (spleefers == null || spleefers.size() == 0) return null;
// create list of spleefers
String comma = SimpleSpleef.ll("feedback.infoComma");
StringBuilder builder = new StringBuilder();
for (int team = Spleefer.TEAM_RED; team >= Spleefer.TEAM_NONE; team--) {
// color
ChatColor teamColor;
switch (team) {
case Spleefer.TEAM_BLUE: teamColor = ChatColor.BLUE; break;
case Spleefer.TEAM_RED: teamColor = ChatColor.RED; break;
default: teamColor = ChatColor.WHITE;
}
// append team
builder.append(SimpleSpleef.ll("feedback.infoTeam",
"[TEAM]", teamColor + SimpleSpleef.ll("feedback.team" + Spleefer.getTeamId(team)) + ChatColor.WHITE)).append(' ');
int i = 0;
for (Spleefer spleefer : spleefers.get()) {
if (i > 0) builder.append(comma); // no ands here...
// in team?
if (spleefer.getTeam() == team) {
// lost or in game?
if (spleefer.hasLost()) builder.append(ChatColor.RED);
else builder.append(ChatColor.GREEN);
builder.append(spleefer.getPlayer().getDisplayName());
builder.append(ChatColor.WHITE);
i++;
}
}
if (i == 0) builder.append("---"); // no players in this team
if (team != Spleefer.TEAM_NONE) builder.append("; "); // separate both team strings
}
return builder.toString();
}
@Override
public boolean team(Player player, String team) {
if (player == null || team == null) return false; // prevent NPEs
// is spleefer?
Spleefer spleefer = spleefers.getSpleefer(player);
if (spleefer == null) return false; // should not happen, because the game handler should have checked that..
// no teams during gaming
if (!isJoinable()) {
player.sendMessage(ChatColor.DARK_RED + SimpleSpleef.ll("errors.teamAlreadyStarted", "[ARENA]", getName()));
return false;
}
// is team command disallowed in the arena?
if (!configuration.getBoolean("teamCommand", true)) {
player.sendMessage(ChatColor.DARK_RED + SimpleSpleef.ll("errors.teamNoTeamCommand", "[ARENA]", getName()));
return false;
}
// parse team string
int teamId;
if (team.equalsIgnoreCase("red")) teamId = Spleefer.TEAM_RED;
else if (team.equalsIgnoreCase("blue")) teamId = Spleefer.TEAM_BLUE;
else { // no valid team name
player.sendMessage(ChatColor.DARK_RED + SimpleSpleef.ll("errors.teamNoValidTeam", "[NAME]", team));
return false;
}
// localize team name
String teamName = SimpleSpleef.ll("feedback." + Spleefer.getTeamId(teamId));
// is the player already part of this team?
if (spleefer.getTeam() == teamId) {
player.sendMessage(ChatColor.DARK_RED + SimpleSpleef.ll("errors.teamAlreadyInTeam", "[TEAM]", teamName));
return false;
}
// clear: join the team
spleefer.setTeam(teamId);
player.sendMessage(ChatColor.GREEN + SimpleSpleef.ll("feedback.team", "[TEAM]", teamName));
// broadcast message of somebody joining a team
String broadcastMessage = ChatColor.DARK_PURPLE + SimpleSpleef.ll("broadcasts.team", "[PLAYER]", player.getDisplayName(), "[ARENA]", getName(), "[TEAM]", teamName);
if (SimpleSpleef.getPlugin().getConfig().getBoolean("settings.announceTeam", false)) {
broadcastMessage(broadcastMessage); // broadcast message
} else {
// send message to all receivers
sendMessage(broadcastMessage, player);
}
// if teamJoiningAlsoReadies is true, also ready player
if (configuration.getBoolean("teamJoiningAlsoReadies", true)) {
spleefer.setReady(true);
checkReadyAndStartGame(); // check status and possibly start the game
}
return true;
}
@Override
public boolean onPlayerInteract(PlayerInteractEvent event) {
if (!isEnabled()) return false; // ignore disabled arenas
Block block = event.getClickedBlock();
if (block == null || event.getPlayer() == null || !hasPlayer(event.getPlayer())) return false; // ignore null blocks and null players and players not in game
if (isJoinable() && configuration.getBoolean("teamCommand", true)) {
// get blocks
ItemStack redBlockMaterial;
try {
redBlockMaterial = MaterialHelper.getItemStackFromString(configuration.getString("teamBlockMaterialRed", null), true);
} catch (Exception e) {
SimpleSpleef.log.warning("[SimpleSpleef] Could not parse teamBlockMaterialRed in arena " + getId());
return true; // ignore exceptions
}
ItemStack blueBlockMaterial;
try {
blueBlockMaterial = MaterialHelper.getItemStackFromString(configuration.getString("teamBlockMaterialBlue", null), true);
} catch (Exception e) {
SimpleSpleef.log.warning("[SimpleSpleef] Could not parse teamBlockMaterialBlue in arena " + getId());
return true; // ignore exceptions
}
// blocks are ok, now check touched material and join team
if (redBlockMaterial != null && redBlockMaterial.getTypeId() == block.getTypeId() && MaterialHelper.isSameBlockType(block, redBlockMaterial)) {
if (team(event.getPlayer(), "red")) return true;
}
if (blueBlockMaterial != null && blueBlockMaterial.getTypeId() == block.getTypeId() && MaterialHelper.isSameBlockType(block, blueBlockMaterial)) {
if (team(event.getPlayer(), "blue")) return true;
}
}
return super.onPlayerInteract(event); // call parent
}
@Override
protected boolean checkGameOver() {
// check if teams are still here
boolean[] stillHere = {false, false};
// check spleefer's status
for (Spleefer spleefer : spleefers.getNotLost()) {
int team = spleefer.getTeam(); //out-of-bounds check
if (team == Spleefer.TEAM_BLUE || team == Spleefer.TEAM_RED)
stillHere[spleefer.getTeam() - 1] = true; // team is still here
}
// do we have a team that isn't here?
for (int i = 0; i < stillHere.length; i++)
if (!stillHere[i]) return true; // one team has lost
return false;
}
@Override
protected void winByTouching(Player player) {
// get team
int team = -99;
Spleefer s;
if ((s = spleefers.getSpleefer(player)) != null) {
team = s.getTeam();
}
if (team == -99) {
SimpleSpleef.log.warning("[SimpleSpleef] Could not determine winning team while touching a block.");
}
for (Spleefer spleefer : spleefers.get()) {
// if not the winning team and not already lost and not in same team
if (spleefer.getTeam() != team && !spleefer.hasLost())
playerLoses(spleefer.getPlayer(), true);
}
}
@Override
protected void broadcastWinners(LinkedList<Spleefer> winners) {
// get the total winners from winners list
String broadcastKey;
String replacePlayer = "";
String team = "---";
// no winner?
if (winners.size() == 0) broadcastKey = "None";
else { // winning team
broadcastKey = ""; // just winTeam
// get winning team
team = SimpleSpleef.ll("feedback.team" + Spleefer.getTeamId(winners.getFirst().getTeam()));
replacePlayer = SpleeferList.getPrintablePlayerList(winners);
}
// broadcast message
String broadcastMessage = ChatColor.GOLD + SimpleSpleef.ll("broadcasts.winTeam" + broadcastKey, "[PLAYER]", replacePlayer, "[ARENA]", getName(), "[TEAM]", team);
sendMessage(broadcastMessage, SimpleSpleef.getPlugin().getConfig().getBoolean("settings.announceWin", true));
}
@Override
protected void teleportPlayersAtGameStart() {
//create teams at game start
createTeams();
// do red or blue spawns exist?
Location blue = LocationHelper.configToExactLocation(configuration.getConfigurationSection("blueSpawn"));
Location red = LocationHelper.configToExactLocation(configuration.getConfigurationSection("redSpawn"));
for (Spleefer spleefer : spleefers.get()) {
int team = spleefer.getTeam();
// if spawn of player is not defined, teleport to normal game spawn
if ((team == Spleefer.TEAM_BLUE && blue == null)
|| (team == Spleefer.TEAM_RED && red == null))
teleportPlayer(spleefer.getPlayer(), "game");
else teleportPlayer(spleefer.getPlayer(), Spleefer.getTeamId(team));
}
}
/**
* even out the players to two teams and tell everybody about it
*/
protected void createTeams() {
// npe checks
if (spleefers == null || spleefers.size() == 0) return;
// list of spleefers of the teams
LinkedList<Spleefer> blueTeam = new LinkedList<Spleefer>();
LinkedList<Spleefer> redTeam = new LinkedList<Spleefer>();
// fill teams with spleefers
for (Spleefer spleefer : spleefers.get()) {
if (spleefer.getTeam() == Spleefer.TEAM_BLUE) redTeam.add(spleefer);
else redTeam.add(spleefer); // move all others to the red team
}
// are the teams unevenly mixed? If yes, even them out on a random basis.
if (redTeam.size() > blueTeam.size()) evenOutTeamLists(blueTeam, redTeam);
else if (blueTeam.size() > redTeam.size()) evenOutTeamLists(redTeam, blueTeam);
// we have the teams, now set teams
for (Spleefer spleefer : blueTeam) spleefer.setTeam(Spleefer.TEAM_BLUE);
for (Spleefer spleefer : redTeam) spleefer.setTeam(Spleefer.TEAM_RED);
// broadcast message of player teams, so everyone knows this...
String broadcastMessage = ChatColor.WHITE + SimpleSpleef.ll("broadcasts.teams", "[TEAMS]", getListOfSpleefers());
sendMessage(broadcastMessage, SimpleSpleef.getPlugin().getConfig().getBoolean("settings.announceTeam", false));
}
/**
* even out the teams
* @param smaller
* @param larger
*/
protected void evenOutTeamLists(LinkedList<Spleefer> smaller, LinkedList<Spleefer> larger) {
// if the size difference is 1, ignore evening out - also ignore 1 member teams
if (larger.size()-1 == smaller.size() || larger.size() <= 1) return;
Random generator = new Random();
while (smaller.size() < larger.size()) { // take one of the red team members from team red to blue until they even out
int index = generator.nextInt(larger.size() -1);
smaller.add(larger.get(index));
larger.remove(index);
}
}
}