Advertisement
Guest User

Untitled

a guest
Oct 25th, 2014
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 53.26 KB | None | 0 0
  1. package me.XxZHALO13Xx.UHC;
  2.  
  3. import me.XxZHALO13Xx.UHC.Countdown.BorderCountdown;
  4. import me.XxZHALO13Xx.UHC.Countdown.MatchCountdown;
  5. import me.XxZHALO13Xx.UHC.Countdown.PVPCountdown;
  6. import me.XxZHALO13Xx.UHC.Countdown.PermadayCountdown;
  7. import me.XxZHALO13Xx.UHC.CustomEvent.*;
  8. import me.XxZHALO13Xx.UHC.Event.UhcEvent;
  9. import me.XxZHALO13Xx.UHC.Notification.DamageNotification;
  10. import me.XxZHALO13Xx.UHC.Notification.ProximityNotification;
  11. import me.XxZHALO13Xx.UHC.Notification.UhcNotification;
  12. import me.XxZHALO13Xx.UHC.Player.UhcPOI;
  13. import me.XxZHALO13Xx.UHC.Player.UhcParticipant;
  14. import me.XxZHALO13Xx.UHC.Player.UhcPlayer;
  15. import me.XxZHALO13Xx.UHC.Player.UhcTeam;
  16. import me.XxZHALO13Xx.UHC.Startpoint.LargeGlassStartPoint;
  17. import me.XxZHALO13Xx.UHC.Startpoint.SmallGlassStartPoint;
  18. import me.XxZHALO13Xx.UHC.Startpoint.UhcStartPoint;
  19. import me.XxZHALO13Xx.UHC.Util.MatchUtils;
  20. import me.XxZHALO13Xx.UHC.Util.PluginChannelUtils;
  21. import org.bukkit.*;
  22. import org.bukkit.block.Block;
  23. import org.bukkit.block.Skull;
  24. import org.bukkit.configuration.Configuration;
  25. import org.bukkit.entity.*;
  26. import me.XxZHALO13Xx.UHC.*;
  27. import org.bukkit.inventory.ItemStack;
  28. import org.bukkit.inventory.Recipe;
  29. import org.bukkit.inventory.ShapedRecipe;
  30. import org.bukkit.inventory.ShapelessRecipe;
  31.  
  32. import java.util.*;
  33.  
  34. /**
  35. * Created by ZH on 10/24/2014.
  36. */
  37. public class UhcMatch {
  38.  
  39.  
  40. private World startingWorld;
  41. private HashMap<Integer, UhcStartPoint> startPoints = new HashMap<Integer, UhcStartPoint>();
  42. private Location lastNotifierLocation;
  43. private Location lastDeathLocation;
  44. private Location lastEventLocation;
  45. private Location lastLogoutLocation;
  46.  
  47. private Boolean permaday = false;
  48. private int permadayTaskId;
  49.  
  50. private ArrayList<UhcStartPoint> availableStartPoints = new ArrayList<UhcStartPoint>();
  51. private HashMap<String, UhcTeam> uhcTeams = new HashMap<String, UhcTeam>(32);
  52.  
  53. private ArrayList<String> launchQueue = new ArrayList<String>();
  54. public static int GOLD_LAYER = 32;
  55. public static int DIAMOND_LAYER = 16;
  56. private ArrayList<UhcParticipant> participantsInMatch = new ArrayList<UhcParticipant>();
  57. private ArrayList<UhcTeam> teamsInMatch = new ArrayList<UhcTeam>();
  58. private Calendar matchStartTime = null;
  59. private int matchTimer = -1;
  60. private long lastMatchTimeAnnouncement = 0;
  61. private ArrayList<Location> calculatedStarts = null;
  62. private boolean pvp = false;
  63. private int spawnKeeperTask = -1;
  64. private TesseractUHC plugin;
  65. private Server server;
  66. private MatchPhase matchPhase = MatchPhase.PRE_MATCH;
  67. private MatchCountdown matchCountdown;
  68. private BorderCountdown borderCountdown;
  69. private PermadayCountdown permadayCountdown;
  70. private PVPCountdown pvpCountdown;
  71. private ArrayList<UhcPOI> uhcPOIs = new ArrayList<UhcPOI>();
  72. private ArrayList<UhcEvent> uhcEvents = new ArrayList<UhcEvent>();
  73. private int locationCheckerTask;
  74. private static int PROXIMITY_THRESHOLD_SQUARED = 10000;
  75. protected static int PLAYER_DAMAGE_ALERT_TICKS = 80; // 4 seconds
  76. protected static int PLAYER_HEAL_ALERT_TICKS = 80; // 4 seconds
  77. public static short DURABILITY_PENALTY_GOLD = 1;
  78. public static short DURABILITY_PENALTY_WOOD = 2;
  79. public static short DURABILITY_PENALTY_STONE = 3;
  80. public static short DURABILITY_PENALTY_IRON = 4;
  81. public static short DURABILITY_PENALTY_DIAMOND = 5;
  82. public static int EVENT_COUNTDOWN_LENGTH = 3; // 3 minute countdown for all match events
  83. private HashMap<String, UhcPlayer> allPlayers = new HashMap<String, UhcPlayer>();
  84. private UhcConfiguration config;
  85. private int borderCheckerTask;
  86. private Integer worldRadiusFinal = null;
  87. private Integer worldRadius = null;
  88.  
  89. // ALL COLORS. Currently doesn't include white.
  90. private static final ChatColor[] COLORS = {ChatColor.BLUE, ChatColor.RED, ChatColor.DARK_GREEN, ChatColor.DARK_PURPLE, ChatColor.YELLOW, ChatColor.GRAY, ChatColor.DARK_GRAY, ChatColor.DARK_AQUA, ChatColor.DARK_RED, ChatColor.LIGHT_PURPLE, ChatColor.GREEN, ChatColor.BLACK, ChatColor.BLUE, ChatColor.AQUA, ChatColor.GOLD};
  91.  
  92. public UhcMatch(TesseractUHC plugin, World startingWorld, Configuration defaults) {
  93.  
  94. this.startingWorld = startingWorld;
  95. this.plugin = plugin;
  96. this.server = plugin.getServer();
  97. this.config = new UhcConfiguration(this, defaults);
  98.  
  99. this.setPermaday(true);
  100. this.setPVP(false);
  101. this.setVanish();
  102. this.enableSpawnKeeper();
  103. this.setWorldBorder(config.getWorldBorder());
  104.  
  105. }
  106.  
  107.  
  108. public UhcConfiguration getConfig() {
  109. return this.config;
  110. }
  111.  
  112.  
  113. /**
  114. * Send a message to all spectators
  115. *
  116. * @param string The message to be sent
  117. */
  118. public void spectatorBroadcast(String string) {
  119. for(UhcPlayer up : getOnlinePlayers()) {
  120. if (up.isSpectator())
  121. up.sendMessage(string);
  122. }
  123. }
  124.  
  125. /**
  126. * Send a message to all ops
  127. *
  128. * @param string The message to be sent
  129. */
  130. public void adminBroadcast(String string) {
  131. broadcast(string,Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
  132. }
  133.  
  134. /**
  135. * Send a message to all players on the server
  136. *
  137. * @param string The message to be sent
  138. */
  139. public void broadcast(String string) {
  140. broadcast(string,Server.BROADCAST_CHANNEL_USERS);
  141. }
  142. /**
  143. * Send a message to all players on a certain team
  144. *
  145. * @param team to be broadcast too
  146. */
  147. public void broadcastTeam(String message, UhcTeam team){
  148. for(UhcParticipant up: team.getMembers()){
  149. up.sendMessage(message);
  150. }
  151. }
  152.  
  153. /**
  154. * Send a message to specific players on the server
  155. *
  156. * @param string The message to be sent
  157. * @param permission The permission level to send the message to
  158. */
  159. private void broadcast(String string, String permission) {
  160. server.broadcast(string, permission);
  161. }
  162.  
  163. /**
  164. * Set time to midday, to keep permaday in effect.
  165. */
  166. private void keepPermaday() {
  167. this.startingWorld.setTime(6000);
  168. }
  169.  
  170. /**
  171. * Enables / disables PVP on overworld
  172. *
  173. * @param pvp Whether PVP is to be allowed
  174. */
  175. public void setPVP(boolean pvp) {
  176. this.pvp = pvp;
  177. startingWorld.setPVP(pvp);
  178.  
  179. adminBroadcast(TesseractUHC.OK_COLOR + "PVP has been " + (pvp ? "enabled" : "disabled") + "!");
  180.  
  181. }
  182.  
  183. /**
  184. * @return Whether PVP is enabled
  185. */
  186. public boolean getPVP() {
  187. return this.pvp;
  188. }
  189.  
  190. /**
  191. * Enables / disables permaday
  192. *
  193. * @param p whether permaday is to be on or off
  194. */
  195. public void setPermaday(boolean p) {
  196. if (p == permaday) return;
  197.  
  198. this.permaday=p;
  199.  
  200. adminBroadcast(TesseractUHC.OK_COLOR + "Permaday has been " + (permaday ? "enabled" : "disabled") + "!");
  201.  
  202.  
  203. if (permaday) {
  204. startingWorld.setTime(6000);
  205. permadayTaskId = server.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
  206. public void run() {
  207. keepPermaday();
  208. }
  209. }, 1200L, 1200L);
  210.  
  211. } else {
  212. server.getScheduler().cancelTask(permadayTaskId);
  213. }
  214. }
  215.  
  216.  
  217. /**
  218. * @return Whether permaday is enabled
  219. */
  220. public boolean getPermaday() {
  221. return this.permaday;
  222. }
  223.  
  224.  
  225.  
  226.  
  227. public UhcStartPoint findStartPoint(String searchParam) {
  228. UhcParticipant up = this.getMatchParticipant(searchParam);
  229. if (up != null) {
  230. // Argument matches a participant
  231. return up.getStartPoint();
  232.  
  233. } else {
  234. try {
  235. int i = Integer.parseInt(searchParam);
  236. return startPoints.get(i);
  237. } catch (Exception e) {
  238. return null;
  239. }
  240. }
  241.  
  242. }
  243.  
  244. private UhcParticipant getMatchParticipant(String name) {
  245. UhcPlayer pl = getExistingPlayer(name);
  246. if (pl != null)
  247. if (pl.isParticipant())
  248. return pl.getParticipant();
  249.  
  250. return null;
  251. }
  252.  
  253.  
  254. /**
  255. * Set a death location for teleporters
  256. *
  257. * @param l The location to be stored
  258. */
  259. public void setLastDeathLocation(Location l) {
  260. // For void deaths, increase y to 0;
  261. if (l.getY() < 0) l.setY(0);
  262. lastDeathLocation = l;
  263. lastEventLocation = l;
  264. }
  265.  
  266. /**
  267. * Set a notification location for teleporters
  268. *
  269. * @param l The location to be stored
  270. */
  271. private void setLastNotifierLocation(Location l) {
  272. lastNotifierLocation = l;
  273. lastEventLocation = l;
  274. }
  275.  
  276. /**
  277. * Set a logout location for teleporters
  278. *
  279. * @param l The location to be stored
  280. */
  281. public void setLastLogoutLocation(Location l) {
  282. lastLogoutLocation = l;
  283. }
  284.  
  285.  
  286.  
  287. /**
  288. * Remove all hostile mobs in the overworld
  289. */
  290. public void butcherHostile() {
  291. for (Entity entity : startingWorld.getEntitiesByClass(LivingEntity.class)) {
  292. if (entity instanceof Monster || entity instanceof MagmaCube || entity instanceof Slime || entity instanceof EnderDragon
  293. || entity instanceof Ghast)
  294. entity.remove();
  295. }
  296. }
  297.  
  298.  
  299. /**
  300. * Start the match
  301. *
  302. * Butcher hostile mobs, turn off permaday, turn on PVP, put all participants in survival and reset all participants.
  303. */
  304. public void startMatch() {
  305. // Remove participants who didn't turn up
  306. if (config.isNoLatecomers())
  307. for (UhcPlayer up : this.allPlayers.values())
  308. if (up.isParticipant() && !up.getParticipant().isLaunched())
  309. this.removeParticipant(up.getName());
  310.  
  311. this.matchCountdown = null;
  312. matchPhase = MatchPhase.MATCH;
  313. startingWorld.setTime(0);
  314. butcherHostile();
  315. server.setSpawnRadius(0);
  316. startingWorld.setDifficulty(Difficulty.HARD);
  317. for (UhcParticipant up : this.getUhcParticipants()) up.start();
  318. setPermaday(false);
  319. setVanish();
  320. broadcast("GO!");
  321.  
  322. // Set up pvp countdown
  323. if (config.getNopvp() > 0) {
  324. new PVPCountdown(config.getNopvp(), plugin, this, true);
  325. } else {
  326. setPVP(true);
  327. }
  328. enableLocationChecker();
  329. enableBorderChecker();
  330. enableMatchTimer();
  331. updatePlayerListCompletely();
  332. server.getPluginManager().callEvent(new UhcMatchStartEvent(this, startingWorld.getSpawnLocation()));
  333.  
  334. }
  335.  
  336. /**
  337. * End the match
  338. *
  339. * Announce the total match duration
  340. */
  341. public void endMatch() {
  342. server.getPluginManager().callEvent(new UhcMatchEndEvent(this, startingWorld.getSpawnLocation()));
  343. broadcast(matchTimeAnnouncement(true));
  344. disableMatchTimer();
  345. matchPhase = MatchPhase.POST_MATCH;
  346. // Put all players into creative
  347. for (UhcPlayer pl : getOnlinePlayers()) pl.setGameMode(GameMode.CREATIVE);
  348. setVanish();
  349. disableLocationChecker();
  350. disableBorderChecker();
  351.  
  352. }
  353.  
  354.  
  355. public void setWorldBorder(Integer nextRadius) {
  356. if (nextRadius==null || nextRadius == 0) {
  357. worldRadiusFinal = null;
  358. worldRadius = null;
  359. return;
  360. }
  361.  
  362. worldRadiusFinal = nextRadius;
  363. if (worldRadiusFinal >= 100) {
  364. worldRadius = worldRadiusFinal-15;
  365. } else {
  366. worldRadius = (int) (worldRadiusFinal * 0.9);
  367. }
  368.  
  369.  
  370. }
  371.  
  372.  
  373. /**
  374. * Starts the match timer
  375. */
  376. private void enableMatchTimer() {
  377. matchStartTime = Calendar.getInstance();
  378.  
  379. // Immediately do the first one
  380. doScheduledTasks();
  381.  
  382. // Repeat every 20 seconds
  383. matchTimer = server.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
  384. public void run() {
  385. doScheduledTasks();
  386. }
  387. }, 420L, 400L);
  388. }
  389.  
  390. /**
  391. * Stops the match timer
  392. */
  393. private void disableMatchTimer() {
  394. if (matchTimer != -1) {
  395. server.getScheduler().cancelTask(matchTimer);
  396. }
  397. }
  398.  
  399. /**
  400. * Get the current match time in seconds
  401. *
  402. * @return Time since the match started, in seconds
  403. */
  404. public long getMatchTime() {
  405. if (matchStartTime == null) return 0;
  406. return MatchUtils.getDuration(matchStartTime, Calendar.getInstance());
  407. }
  408.  
  409. /**
  410. * Display the current match time if it is a multiple of 30.
  411. */
  412. private void doScheduledTasks() {
  413. // Get current match time
  414. long matchTime = getMatchTime() / 60;
  415.  
  416. // Make a match time announcement if necessary
  417. if (config.getAnnouncementinterval() > 0) {
  418. if (matchTime % config.getAnnouncementinterval() == 0 && matchTime > this.lastMatchTimeAnnouncement) {
  419. broadcast(matchTimeAnnouncement(false));
  420. this.lastMatchTimeAnnouncement = matchTime;
  421. }
  422. }
  423.  
  424. // Process any UhcEvents that are due
  425. for(UhcEvent e : this.uhcEvents) {
  426. if (!e.isHandled() && e.getTime() <= matchTime + e.getCountdownLength()) {
  427. e.startCountdown((int)(e.getTime() - matchTime));
  428. }
  429.  
  430. }
  431. }
  432.  
  433.  
  434. /**
  435. * Get all participants currently registered with the game
  436. *
  437. * @return All registered participants
  438. */
  439. private Collection<UhcParticipant> getUhcParticipants() {
  440. ArrayList<UhcParticipant> participants = new ArrayList<UhcParticipant>();
  441.  
  442. for (UhcTeam team : this.getTeams())
  443. for (UhcParticipant up : team.getMembers())
  444. participants.add(up);
  445.  
  446. return participants;
  447. }
  448.  
  449. private UhcTeam createTeam(String identifier, String name, UhcStartPoint startPoint) {
  450. // Fail if team exists
  451. if (existsTeam(identifier)) return null;
  452.  
  453. UhcTeam team = new UhcTeam(identifier, name, startPoint,COLORS[uhcTeams.size() % COLORS.length]);
  454. uhcTeams.put(identifier.toLowerCase(), team);
  455. return team;
  456. }
  457.  
  458.  
  459. private UhcParticipant createParticipant(UhcPlayer pl, UhcTeam team) {
  460. // Fail if player exists
  461. if (pl.isParticipant()) return null;
  462.  
  463. UhcParticipant up = new UhcParticipant(pl, team);
  464. pl.setParticipant(up);
  465. team.addMember(up);
  466. return up;
  467. }
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474. public boolean existsTeam(String identifier) {
  475. return uhcTeams.containsKey(identifier.toLowerCase());
  476. }
  477.  
  478. /**
  479. * Compares a passed name to existing team names
  480. *
  481. * @param name of proposed team
  482. * @return true if an existing team has passed team else false
  483. */
  484. public boolean existsTeamByName(String name) {
  485. for(UhcTeam team : this.getTeams()){
  486. if(team.getName().equals(name))
  487. return true;
  488. }
  489. return false;
  490. }
  491.  
  492.  
  493.  
  494. public UhcTeam getTeam(String identifier) {
  495. return uhcTeams.get(identifier.toLowerCase());
  496. }
  497.  
  498.  
  499. public UhcParticipant getParticipantByIndex(int index) {
  500. if (index < participantsInMatch.size())
  501. return participantsInMatch.get(index);
  502. else
  503. return null;
  504. }
  505.  
  506. /**
  507. * Add the team as detailed, and assign them a start point
  508. *
  509. * @param identifier The team's short identifier
  510. * @param name The full name of the team
  511. * @return success or failure
  512. */
  513. public boolean addTeam(String identifier, String name) {
  514. // Check that there are available start points
  515. if (!roomForAnotherTeam()) return false;
  516.  
  517. // Check that the team doesn't exist already
  518. if (existsTeam(identifier)) return false;
  519.  
  520. // Get them a start point
  521. Random rand = new Random();
  522. UhcStartPoint start = availableStartPoints.remove(rand.nextInt(availableStartPoints.size()));
  523.  
  524. // Create the team
  525. UhcTeam team = createTeam(identifier, name, start);
  526. start.setTeam(team);
  527. teamsInMatch.add(team);
  528.  
  529. // Send update to the spectators
  530. if (getConfig() != null && !getConfig().isFFA()){
  531. PluginChannelUtils.messageSpectators("team", name, "init");
  532. PluginChannelUtils.messageSpectators("team", name, "color", team.getColor().toString());
  533. }
  534.  
  535. return true;
  536. }
  537.  
  538. /**
  539. * Checks if there is room for another team to be created
  540. *
  541. * @return Whether there is another start point
  542. */
  543. public boolean roomForAnotherTeam() {
  544. return (availableStartPoints.size()>0);
  545. }
  546.  
  547.  
  548. public boolean addParticipant(UhcPlayer pl, String teamIdentifier) {
  549. // If player is op, fail
  550. if (pl.isAdmin()) return false;
  551.  
  552. // If player is already a participant, fail
  553. if (pl.isParticipant()) return false;
  554.  
  555. // If the player has the autoreferee-client mod, fail
  556. if (pl.getAutoRefereeClientEnabled()) {
  557. this.spectatorBroadcast(pl.getDisplayName() + ChatColor.DARK_GRAY + " attempted to log in with a modified client!");
  558. pl.sendMessage(TesseractUHC.WARN_COLOR + " you attempted to join with a modified client mod.");
  559. return false;
  560. }
  561.  
  562. // Get the team
  563. UhcTeam team = getTeam(teamIdentifier);
  564.  
  565. // If team doesn't exist, fail
  566. if (team == null) return false;
  567.  
  568. // If player is a spectator, make them not one
  569. if (pl.isSpectator()) pl.makeNotSpectator();
  570.  
  571. // Create the player
  572. UhcParticipant up = createParticipant(pl, team);
  573.  
  574. // If player wasn't created, fail
  575. if (up == null) return false;
  576.  
  577. // Message client mod that player joined team
  578. if (getConfig() != null) // Don't do this if we are still busy constructing match and config
  579. PluginChannelUtils.messageSpectators("team", team.getName(), "player", "+" + up.getName());
  580.  
  581. participantsInMatch.add(up);
  582. return true;
  583. }
  584.  
  585.  
  586. public boolean addSoloParticipant (UhcPlayer pl) {
  587. // If player is op, fail
  588. if (pl.isAdmin()) return false;
  589.  
  590. // If player is already a participant, fail
  591. if (pl.isParticipant()) return false;
  592.  
  593. // If the player has the autoreferee-client mod, fail
  594. if (pl.getAutoRefereeClientEnabled()) {
  595. this.spectatorBroadcast(pl.getDisplayName() + ChatColor.DARK_GRAY + " attempted to log in with a modified client!");
  596. pl.sendMessage(TesseractUHC.WARN_COLOR + " you attempted to join with a modified client mod.");
  597. return false;
  598. }
  599.  
  600. // If player is a spectator, make them not one
  601. if (pl.isSpectator()) pl.makeNotSpectator();
  602.  
  603. // Create a team of one for the player
  604. String teamName = pl.getName();
  605. if (!addTeam(teamName, teamName)) return false;
  606.  
  607. // Add the new player to the team of one, and return the result
  608. return addParticipant(pl, teamName);
  609.  
  610. }
  611.  
  612.  
  613.  
  614. public boolean launch(UhcPlayer pl) {
  615.  
  616. if (!pl.isParticipant()) return false;
  617.  
  618. UhcParticipant up = pl.getParticipant();
  619.  
  620. // If player already launched, ignore
  621. if (up.isLaunched()) return false;
  622.  
  623. // Get the player
  624. Player p = server.getPlayerExact(up.getName());
  625.  
  626. // If player not online, return
  627. if (p == null) return false;
  628.  
  629.  
  630. up.sendToStartPoint();
  631.  
  632. up.setLaunched(true);
  633. up.sendMessage(ChatColor.GOLD + "This is " + ChatColor.ITALIC + config.getMatchTitle() + "\n"
  634. + ChatColor.RESET + ChatColor.AQUA + "To find out the parameters for this game, type " + ChatColor.GOLD + "/params" + "\n"
  635. + ChatColor.AQUA + "To view the match status at any time, type " + ChatColor.GOLD + "/match");
  636.  
  637. // Trigger a join event
  638. server.getPluginManager().callEvent(new UhcJoinEvent(this, up.getStartPoint().getLocation(), p));
  639.  
  640. return true;
  641.  
  642.  
  643.  
  644. }
  645.  
  646.  
  647.  
  648. /**
  649. * Remove the given player, removing them from the match, and their team.
  650. *
  651. * The player will be teleported back to spawn if they are still on the server
  652. *
  653. * @param name The player to be removed
  654. * @return Whether the removal succeeded
  655. */
  656. public boolean removeParticipant(String name) {
  657. UhcPlayer pl = getPlayer(name);
  658.  
  659. if (pl.isParticipant()) {
  660.  
  661. // Remove them from their team
  662. UhcTeam team = pl.getParticipant().getTeam();
  663. team.removeMember(pl.getParticipant());
  664.  
  665. // Remove them from the match
  666. participantsInMatch.remove(pl.getParticipant());
  667.  
  668. // Mark them as a non participant
  669. getPlayer(name).setParticipant(null);
  670.  
  671. // Message client mod that player left team
  672. PluginChannelUtils.messageSpectators("team", team.getName(), "player", "-" + pl.getName());
  673.  
  674. // Remove team if empty
  675. if(team.getMembers().size() == 0){
  676. removeTeam(team.getIdentifier());
  677. if (matchPhase == MatchPhase.MATCH && !config.isFFA()) {
  678. broadcast(ChatColor.GOLD + team.getName() + " now has no members.");
  679. }
  680. }
  681.  
  682.  
  683. if (matchPhase == MatchPhase.MATCH) {
  684. broadcast(ChatColor.GOLD + pl.getName() + " has left the match");
  685. broadcastMatchStatus();
  686. }
  687. pl.teleport(startingWorld.getSpawnLocation());
  688.  
  689. getPlayer(name).makeSpectator();
  690. return true;
  691. } else return false;
  692. }
  693.  
  694. /**
  695. * Remove the given team, which must be empty, from the match, and free up its start point.
  696. *
  697. * @param identifier The team to remove
  698. * @return Whether the removal succeeded
  699. */
  700. public boolean removeTeam(String identifier) {
  701. UhcTeam team = getTeam(identifier);
  702.  
  703. // If team not found, fail
  704. if (team == null) return false;
  705.  
  706. // If team not empty, fail
  707. if (team.playerCount()>0) return false;
  708.  
  709. uhcTeams.remove(identifier.toLowerCase());
  710. teamsInMatch.remove(team);
  711.  
  712. // Free up the start point
  713. UhcStartPoint sp = team.getStartPoint();
  714. sp.setTeam(null);
  715. sp.makeSign();
  716. sp.emptyChest();
  717. availableStartPoints.add(sp);
  718.  
  719. // Message client mod that player left team
  720. PluginChannelUtils.messageSpectators("team", team.getName(), "destroy");
  721.  
  722. return true;
  723. }
  724.  
  725.  
  726. /**
  727. * Pre-warn 2 minutes before the match is due to begin, and inform players who haven't joined yet that
  728. * they have 30 seconds
  729. */
  730. public void preWarn() {
  731. // For all players on the server, check if they are joined up
  732. for(Player p : server.getOnlinePlayers())
  733. if (!this.getPlayer(p).isSpectator() && !this.getPlayer(p).isParticipant())
  734. p.sendMessage(ChatColor.GOLD + "Joining the match will be disabled in 30 seconds. If you want to play, use /join.");
  735.  
  736. }
  737. /**
  738. * Start the launching phase, and launch all players who have been added to the game
  739. */
  740. public boolean launchAll() {
  741. // If already launched, do nothing.
  742. if (matchPhase != MatchPhase.PRE_MATCH) return false;
  743.  
  744. matchPhase = MatchPhase.LAUNCHING;
  745. disableSpawnKeeper();
  746. if (config.isUHC()) setupModifiedRecipes();
  747. setVanish(); // Update vanish status
  748. butcherHostile();
  749. sortParticipantsInMatch();
  750.  
  751. // Fill bonus chests
  752. for (UhcTeam team : getTeams()) {
  753. team.getStartPoint().makeSign();
  754. team.getStartPoint().fillChest(config.getBonusChest());
  755. }
  756.  
  757. // Add all players to the launch queue
  758. for(UhcParticipant up : getUhcParticipants())
  759. if (!up.isLaunched()) addToLaunchQueue(up);
  760.  
  761. // Make all others spectators
  762. for(UhcPlayer pl : getOnlinePlayers())
  763. if (!pl.isParticipant())
  764. pl.makeSpectator();
  765.  
  766.  
  767. // Begin launching
  768. launchNext();
  769. return true;
  770. }
  771.  
  772.  
  773. private void sortParticipantsInMatch() {
  774. // Refill the playersInMatch arraylist, sorting players into order.
  775. participantsInMatch.clear();
  776. for (UhcTeam team : teamsInMatch)
  777. for (UhcParticipant up : team.getMembers())
  778. participantsInMatch.add(up);
  779.  
  780.  
  781.  
  782. }
  783.  
  784.  
  785. private void launchNext() {
  786. if (this.launchQueue.size()==0) {
  787. adminBroadcast(TesseractUHC.OK_COLOR + "Launching complete");
  788. return;
  789. }
  790.  
  791. String playerName = this.launchQueue.remove(0);
  792. UhcPlayer up = this.getPlayer(playerName);
  793. launch(up);
  794.  
  795. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  796. public void run() {
  797. launchNext();
  798. }
  799. }, 20L);
  800.  
  801. }
  802.  
  803. private void addToLaunchQueue(UhcParticipant up) {
  804. this.launchQueue.add(up.getName().toLowerCase());
  805. }
  806.  
  807. public void scheduleDamageNotification(final DamageNotification n, final Location l) {
  808. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  809. public void run() {
  810. performDamageNotification(n, l);
  811. }
  812. });
  813. }
  814.  
  815. private void performDamageNotification(DamageNotification n, Location l) {
  816. // Don't notify if health hasn't changed (due to armor, resistance, etc)
  817. if (!n.healthChanged()) return;
  818.  
  819. if (config.isDamageAlerts())
  820. sendNotification(n, l);
  821. else
  822. sendSpectatorNotification(n, l);
  823.  
  824. }
  825.  
  826. public void schedulePlayerListUpdate(final UhcPlayer pl) {
  827. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  828. public void run() {
  829. pl.updatePlayerListName();
  830. }
  831. });
  832. }
  833.  
  834. public void updatePlayerListCompletely() {
  835. for (UhcPlayer pl : this.getOnlinePlayers()) {
  836. pl.updatePlayerListName();
  837. }
  838. }
  839.  
  840.  
  841. private void enableSpawnKeeper() {
  842. spawnKeeperTask = server.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
  843. public void run() {
  844. runSpawnKeeper();
  845. }
  846. }, 40L, 40L);
  847. }
  848.  
  849. private void disableSpawnKeeper() {
  850. server.getScheduler().cancelTask(spawnKeeperTask);
  851. }
  852.  
  853. private void runSpawnKeeper() {
  854. boolean keep = (startingWorld.getSpawnLocation().getBlockY() >= 128);
  855. for (UhcPlayer pl : getOnlinePlayers()) {
  856. if (keep && pl.getLocation().getY() < 128 && !pl.isSpectator()) {
  857. pl.teleport(startingWorld.getSpawnLocation(), null);
  858. }
  859. pl.heal();
  860. pl.feed();
  861. }
  862. }
  863.  
  864. private void enableBorderChecker() {
  865. borderCheckerTask = server.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
  866. public void run() {
  867. runBorderChecker();
  868. }
  869. }, 10L, 10L);
  870. }
  871.  
  872. private void disableBorderChecker() {
  873. server.getScheduler().cancelTask(borderCheckerTask);
  874. }
  875.  
  876. private void runBorderChecker() {
  877. // If there is no world border, do nothing
  878. if (worldRadiusFinal == null) return;
  879.  
  880. // Cycle through all UhcPlayers, checking their location
  881. for (UhcParticipant up : participantsInMatch) {
  882. if (!up.getPlayer().isOnline()) continue;
  883. if (up.isOutsideBorder(worldRadius)) {
  884. if (up.getPlayer().getLocation().getWorld().equals(startingWorld)
  885. && up.isOutsideBorder(worldRadiusFinal)) {
  886.  
  887. // Player is outside the hard world boundary in the overworld, TP them back
  888. Location l = up.getPlayer().getLocation();
  889.  
  890. double newX = l.getX();
  891. double newZ = l.getZ();
  892. if (newX > worldRadiusFinal) newX = worldRadius;
  893. if (newZ > worldRadiusFinal) newZ = worldRadius;
  894. if (newX < -worldRadiusFinal) newX = -worldRadius;
  895. if (newZ < -worldRadiusFinal) newZ = -worldRadius;
  896.  
  897. Location l2 = l.clone();
  898. l2.setX(newX);
  899. l2.setZ(newZ);
  900. l2.setY(l2.getWorld().getHighestBlockYAt(l2));
  901. up.getPlayer().teleport(l2);
  902. up.clearWorldEdgeWarning();
  903. } else {
  904. // Player is outside the inner world border in the overworld.
  905. // Calculate the nearest point on the border, and play the noteblock sound from there.
  906. Location l = up.getPlayer().getLocation();
  907.  
  908. double newX = l.getX();
  909. double newZ = l.getZ();
  910. if (newX > worldRadius) newX = worldRadiusFinal;
  911. if (newZ > worldRadius) newZ = worldRadiusFinal;
  912. if (newX < -worldRadius) newX = -worldRadiusFinal;
  913. if (newZ < -worldRadius) newZ = -worldRadiusFinal;
  914.  
  915. Location l2 = l.clone();
  916. l2.setX(newX);
  917. l2.setZ(newZ);
  918.  
  919. up.doWorldEdgeWarning(l2);
  920. }
  921. } else {
  922. up.clearWorldEdgeWarning();
  923. }
  924. }
  925. }
  926.  
  927.  
  928.  
  929. /**
  930. * Send warnings to players who are outside the new border
  931. * @param newRadius
  932. */
  933. public void sendBorderWarnings(int newRadius) {
  934. if (newRadius == 0) return;
  935.  
  936. // Cycle through all UhcPlayers, checking their location
  937. for (UhcParticipant up : participantsInMatch) {
  938. if (!up.getPlayer().isOnline()) continue;
  939. if (up.isOutsideBorder(newRadius)) {
  940. up.sendMessage(ChatColor.YELLOW + "Warning! You are currently OUTSIDE the new world border.");
  941. }
  942. }
  943. }
  944.  
  945. private void enableLocationChecker() {
  946. locationCheckerTask = server.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
  947. public void run() {
  948. runLocationChecker();
  949. }
  950. }, 200L, 600L);
  951. }
  952.  
  953. private void disableLocationChecker() {
  954. server.getScheduler().cancelTask(locationCheckerTask);
  955. }
  956.  
  957. private void runLocationChecker() {
  958. // Cycle through all UhcPlayers
  959. for (int i = 0; i < participantsInMatch.size(); i++) {
  960. UhcParticipant up = participantsInMatch.get(i);
  961.  
  962. // Check proximity to other players (only if not on same team).
  963. int j = i + 1;
  964. while (j < participantsInMatch.size()) {
  965. // Check proximity of player up to player j
  966. UhcParticipant up2 = participantsInMatch.get(j);
  967. if (up.getTeam() != up2.getTeam()) {
  968. if (checkProximity(up, up2)) {
  969. sendSpectatorNotification(new ProximityNotification(up, up2), server.getPlayerExact(up.getName()).getLocation());
  970. }
  971. }
  972. j++;
  973. }
  974.  
  975. // Check proximity to all POIs.
  976. for (UhcPOI poi : uhcPOIs) {
  977. if (checkProximity(up, poi)) {
  978. sendSpectatorNotification(new ProximityNotification(up, poi), server.getPlayerExact(up.getName()).getLocation());
  979. }
  980. }
  981.  
  982. // Trigger a location event
  983. Location l = up.getPlayer().getLocation();
  984. if (l != null) server.getPluginManager().callEvent(new UhcPlayerLocationUpdateEvent(this, l, up.getPlayer().getPlayer()));
  985. }
  986. }
  987.  
  988. private boolean locationsAreClose(Location l1, Location l2) {
  989. if (!l1.getWorld().equals(l2.getWorld())) return false;
  990. return (l1.distanceSquared(l2) < (PROXIMITY_THRESHOLD_SQUARED));
  991. }
  992.  
  993. private boolean checkProximity(UhcParticipant player, UhcParticipant enemy) {
  994. Player p1 = server.getPlayerExact(player.getName());
  995. Player p2 = server.getPlayerExact(enemy.getName());
  996. if (p1 == null || p2 == null) return false;
  997.  
  998. if (player.isNearTo(enemy)) {
  999. if (!locationsAreClose(p1.getLocation(), p2.getLocation()))
  1000. player.setNearTo(enemy, false);
  1001. return false;
  1002. } else {
  1003. if (locationsAreClose(p1.getLocation(),p2.getLocation())) {
  1004. player.setNearTo(enemy, true);
  1005. return true;
  1006. }
  1007. return false;
  1008. }
  1009. }
  1010.  
  1011. private boolean checkProximity(UhcParticipant player, UhcPOI poi) {
  1012. Player p1 = server.getPlayerExact(player.getName());
  1013. if (p1 == null) return false;
  1014.  
  1015. if (player.isNearTo(poi)) {
  1016. if (!locationsAreClose(p1.getLocation(), poi.getLocation()))
  1017. player.setNearTo(poi, false);
  1018. return false;
  1019. } else {
  1020. if (locationsAreClose(p1.getLocation(), poi.getLocation())) {
  1021. player.setNearTo(poi, true);
  1022. return true;
  1023. }
  1024. return false;
  1025. }
  1026. }
  1027.  
  1028. public void clearStartPoints() {
  1029. startPoints.clear();
  1030. availableStartPoints.clear();
  1031. }
  1032. /**
  1033. * Create a new start point at a given location
  1034. *
  1035. * @param number The start point's number
  1036. * @param l The location of the start point
  1037. * @param buildTrough Whether to add a starting trough
  1038. * @return The created start point
  1039. */
  1040. private UhcStartPoint createStartPoint(int number, Location l, Boolean large, Boolean buildTrough) {
  1041. // Check there is not already a start point with this number
  1042. if (startPoints.containsKey(number))
  1043. return null;
  1044.  
  1045. UhcStartPoint sp;
  1046. if (large)
  1047. sp = new LargeGlassStartPoint(number, l, true);
  1048. else
  1049. sp = new SmallGlassStartPoint(number, l, true);
  1050.  
  1051. if (buildTrough) sp.buildStartingTrough();
  1052.  
  1053. startPoints.put(number, sp);
  1054. availableStartPoints.add(sp);
  1055.  
  1056. return sp;
  1057. }
  1058.  
  1059. /**
  1060. * Create a new start point at a given location, with optional starting trough
  1061. *
  1062. * @param number The start point's number
  1063. * @param world The world to create the start point
  1064. * @param x x coordinate of the start point
  1065. * @param y y coordinate of the start point
  1066. * @param z z coordinate of the start point
  1067. * @param buildTrough Whether to add a starting trough
  1068. * @return The created start point
  1069. */
  1070. public UhcStartPoint createStartPoint(int number, World world, Double x, Double y, Double z, Boolean large, Boolean buildTrough) {
  1071. return createStartPoint(number, new Location(world, x, y, z), large, buildTrough);
  1072. }
  1073.  
  1074. /**
  1075. * Create a new start point at a given location, giving it the next available number
  1076. *
  1077. * @param l The location of the start point
  1078. * @param buildTrough Whether to add a starting trough
  1079. * @return The created start point
  1080. */
  1081. private UhcStartPoint createStartPoint(Location l, Boolean large, Boolean buildTrough) {
  1082. return createStartPoint(getNextAvailableStartNumber(), l, large, buildTrough);
  1083. }
  1084.  
  1085. /**
  1086. * Add a new start point at a given location, giving it the next available number.
  1087. *
  1088. * This function will also update the saved match data.
  1089. *
  1090. * @param x x coordinate of the start point
  1091. * @param y y coordinate of the start point
  1092. * @param z z coordinate of the start point
  1093. * @param buildTrough Whether to add a starting trough
  1094. * @return The created start point
  1095. */
  1096. public UhcStartPoint addStartPoint(Double x, Double y, Double z, Boolean buildTrough) {
  1097. UhcStartPoint sp = createStartPoint(new Location(startingWorld, x, y, z), !config.isFFA(), buildTrough);
  1098. if (sp != null) config.saveMatchParameters();
  1099. return sp;
  1100. }
  1101.  
  1102.  
  1103. /**
  1104. * Determine the lowest unused start number
  1105. *
  1106. * @return The lowest available start point number
  1107. */
  1108. public int getNextAvailableStartNumber() {
  1109. int n = 1;
  1110. while (startPoints.containsKey(n))
  1111. n++;
  1112. return n;
  1113. }
  1114.  
  1115.  
  1116.  
  1117.  
  1118. /**
  1119. * @return The number of players still in the match
  1120. */
  1121. public int countParticipantsInMatch() {
  1122. return participantsInMatch.size();
  1123. }
  1124.  
  1125.  
  1126. /**
  1127. * @return The number of teams still in the match
  1128. */
  1129. public int countTeamsInMatch() {
  1130. return teamsInMatch.size();
  1131. }
  1132.  
  1133. public void placeHeadDelayed(final Location l, final String name) {
  1134. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  1135. public void run() {
  1136. placeHead(l,name);
  1137. }
  1138. });
  1139. }
  1140.  
  1141. public void placeHead(Location l, String name) {
  1142. Block b = l.getBlock();
  1143.  
  1144. while(b != null && b.getType() != Material.AIR) {
  1145. // If we have reached the top of the world, give up and don't place it anywhere.
  1146. if (b.getY() == b.getWorld().getMaxHeight() - 1) return;
  1147. b = b.getRelative(0, 1, 0);
  1148. }
  1149.  
  1150. b.setTypeIdAndData(Material.SKULL.getId(), (byte) 1, true);
  1151.  
  1152. Skull s = (Skull) b.getState();
  1153. s.setSkullType(SkullType.PLAYER);
  1154. s.setRotation(MatchUtils.getBlockFaceDirection(l));
  1155. s.setOwner(name);
  1156. s.update(true);
  1157.  
  1158. }
  1159.  
  1160. public void handleParticipantDeath(final UhcParticipant up) {
  1161. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  1162. public void run() {
  1163. processParticipantDeath(up);
  1164. }
  1165. });
  1166.  
  1167. }
  1168.  
  1169. public void handleDragonKill(final UhcParticipant killer) {
  1170. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  1171. public void run() {
  1172. processDragonKill(killer);
  1173. }
  1174. });
  1175.  
  1176. }
  1177.  
  1178. public void handleEliminatedPlayer(final UhcPlayer p) {
  1179. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  1180. public void run() {
  1181. p.makeSpectator();
  1182. }
  1183. });
  1184.  
  1185. }
  1186.  
  1187. /**
  1188. * Process the death of a player
  1189. *
  1190. * @param up The player who died
  1191. */
  1192. private void processParticipantDeath(final UhcParticipant up) {
  1193. // Set them as dead
  1194. up.setDead(true);
  1195.  
  1196. // Reduce survivor counts
  1197. participantsInMatch.remove(up);
  1198.  
  1199. // Trigger a UhcEliminationEvent
  1200. UhcTeam team = up.getTeam();
  1201. if (team.aliveCount() == 0)
  1202. server.getPluginManager().callEvent(new UhcEliminationEvent(this, up.getPlayer().getLocation(), team.getIdentifier(), team.getName(), countTeamsInMatch() - 1));
  1203.  
  1204. if (!config.isDragonMode() && config.isFFA() && countParticipantsInMatch() == 1) {
  1205. processVictory(participantsInMatch.get(0));
  1206. return;
  1207. }
  1208.  
  1209. if (team != null && team.aliveCount()<1) {
  1210. teamsInMatch.remove(team);
  1211. if (!config.isDragonMode() && !config.isFFA() && countTeamsInMatch() == 1) {
  1212. processVictory(teamsInMatch.get(0));
  1213. return;
  1214. }
  1215. }
  1216.  
  1217. if (countParticipantsInMatch() == 0) endMatch();
  1218.  
  1219. broadcastMatchStatus();
  1220.  
  1221. // Set a timer to remove them from the server after 90 seconds, if deathban is enabled
  1222. if (config.getDeathban()) {
  1223. server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  1224. public void run() {
  1225. if (matchPhase == MatchPhase.MATCH) {
  1226. Player p = up.getPlayer().getPlayer();
  1227. if (p != null) p.kickPlayer("Thanks for playing!");
  1228. }
  1229. }
  1230. },2400L);
  1231. }
  1232. }
  1233.  
  1234. private void processDragonKill(UhcParticipant winner) {
  1235. if (config.isFFA()) {
  1236. broadcast(ChatColor.GOLD + "The winner is: " + winner.getName() + "!");
  1237. } else {
  1238. broadcast(ChatColor.GOLD + "The winner is: " + winner.getTeam().getName() + "!");
  1239. }
  1240. endMatch();
  1241. }
  1242.  
  1243.  
  1244. private void processVictory(UhcTeam winner) {
  1245. broadcast(ChatColor.GOLD + "The winner is: " + winner.getName() + "!");
  1246. endMatch();
  1247. for (UhcParticipant up : winner.getMembers())
  1248. if (up.getPlayer().isActiveParticipant()) up.getPlayer().makeSpectator();
  1249. server.getPluginManager().callEvent(new UhcVictoryEvent(this, this.getStartingWorld().getSpawnLocation(), winner.getIdentifier(), winner.getName()));
  1250. }
  1251.  
  1252. private void processVictory(UhcParticipant winner) {
  1253. broadcast(ChatColor.GOLD + "The winner is: " + winner.getName() + "!");
  1254. endMatch();
  1255. winner.getPlayer().makeSpectator();
  1256. server.getPluginManager().callEvent(new UhcVictoryEvent(this, this.getStartingWorld().getSpawnLocation(), winner.getTeam().getName(), winner.getTeam().getName()));
  1257. }
  1258.  
  1259. /**
  1260. * Publicly announce how many players are still in the match
  1261. */
  1262. private void broadcastMatchStatus() {
  1263. // Make no announcement if match has ended
  1264. if (matchPhase != MatchPhase.POST_MATCH)
  1265. broadcast(matchStatusAnnouncement());
  1266.  
  1267. }
  1268.  
  1269. /**
  1270. * Get the text of a match time announcement
  1271. *
  1272. * @param precise Whether to give a precise time (00:00:00) instead of (xx minutes)
  1273. * @return Current match time as a nicely-formatted string
  1274. */
  1275. public String matchTimeAnnouncement(boolean precise) {
  1276. if (matchPhase == MatchPhase.PRE_MATCH || matchPhase == MatchPhase.LAUNCHING)
  1277. return TesseractUHC.MAIN_COLOR + "Match time: " + TesseractUHC.SIDE_COLOR + MatchUtils.formatDuration(0, precise);
  1278. else
  1279. return TesseractUHC.MAIN_COLOR + "Match time: " + TesseractUHC.SIDE_COLOR + MatchUtils.formatDuration(matchStartTime, Calendar.getInstance(), precise);
  1280.  
  1281. }
  1282. /**
  1283. * Get the text of a match status announcement
  1284. *
  1285. * @return List of remaining players / teams
  1286. */
  1287. public String matchStatusAnnouncement() {
  1288. if (this.matchPhase == MatchPhase.PRE_MATCH) {
  1289. if (config.isFFA()) {
  1290. int c = countParticipantsInMatch();
  1291. return c + " player" + (c != 1 ? "s have" : " has") + " joined";
  1292. } else {
  1293. int c = countTeamsInMatch();
  1294. return c + " team" + (c != 1 ? "s have" : " has") + " joined";
  1295. }
  1296. }
  1297. if (config.isFFA()) {
  1298. int c = countParticipantsInMatch();
  1299. if (c == 0)
  1300. return "There are no surviving players";
  1301. if (c == 1)
  1302. return "1 surviving player: " + participantsInMatch.get(0).getName();
  1303.  
  1304. if (c <= 4) {
  1305. String message = c + " surviving players: ";
  1306. for (UhcParticipant up : participantsInMatch)
  1307. message += up.getName() + ", ";
  1308.  
  1309. return message.substring(0, message.length()-2);
  1310. }
  1311.  
  1312. return c + " surviving players";
  1313.  
  1314. } else {
  1315. int c = countTeamsInMatch();
  1316. if (c == 0)
  1317. return "There are no surviving teams";
  1318. if (c == 1)
  1319. return "1 surviving team: " + teamsInMatch.get(0).getName();
  1320.  
  1321. if (c <= 4) {
  1322. String message = c + " surviving teams: ";
  1323. for (UhcTeam t : teamsInMatch)
  1324. message += t.getName() + ", ";
  1325.  
  1326. return message.substring(0, message.length()-2);
  1327. }
  1328.  
  1329. return c + " surviving teams";
  1330.  
  1331. }
  1332. }
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343. public void setVanish() {
  1344. for(UhcPlayer pl : getOnlinePlayers()) pl.setVanish();
  1345. }
  1346.  
  1347.  
  1348.  
  1349. public ArrayList<Location> getCalculatedStarts() {
  1350. return calculatedStarts;
  1351. }
  1352.  
  1353. public void setCalculatedStarts(ArrayList<Location> calculatedStarts) {
  1354. this.calculatedStarts = calculatedStarts;
  1355. }
  1356.  
  1357. public HashMap<Integer, UhcStartPoint> getStartPoints() {
  1358. return startPoints;
  1359. }
  1360.  
  1361. public int countAvailableStartPoints() {
  1362. return availableStartPoints.size();
  1363. }
  1364.  
  1365. public World getStartingWorld() {
  1366. return startingWorld;
  1367. }
  1368.  
  1369. public Location getLastEventLocation() {
  1370. return lastEventLocation;
  1371. }
  1372.  
  1373. public void setLastEventLocation(Location lastEventLocation) {
  1374. this.lastEventLocation = lastEventLocation;
  1375. }
  1376.  
  1377. public Location getLastNotifierLocation() {
  1378. return lastNotifierLocation;
  1379. }
  1380.  
  1381. public Location getLastDeathLocation() {
  1382. return lastDeathLocation;
  1383. }
  1384.  
  1385. public Location getLastLogoutLocation() {
  1386. return lastLogoutLocation;
  1387. }
  1388.  
  1389.  
  1390.  
  1391.  
  1392. public MatchPhase getMatchPhase() {
  1393. return matchPhase;
  1394. }
  1395.  
  1396. public void sendNotification(UhcNotification n, Location l) {
  1397. setLastNotifierLocation(l);
  1398. String message = n.formatForPlayers();
  1399. if (message != null) this.broadcast(message);
  1400. }
  1401.  
  1402. public void sendSpectatorNotification(UhcNotification n, Location l) {
  1403. setLastNotifierLocation(l);
  1404. String message = n.formatForStreamers();
  1405. if (message != null) this.spectatorBroadcast(message);
  1406.  
  1407. }
  1408.  
  1409. public boolean startMatchCountdown(int countLength) {
  1410. if ((this.matchCountdown == null || !this.matchCountdown.isActive()) && (this.matchPhase == MatchPhase.LAUNCHING || this.matchPhase == MatchPhase.PRE_MATCH)) {
  1411. this.matchCountdown = new MatchCountdown(countLength, plugin, this);
  1412. return true;
  1413. }
  1414. return false;
  1415.  
  1416. }
  1417.  
  1418. public boolean cancelMatchCountdown() {
  1419. if (this.matchCountdown == null) return false;
  1420. return matchCountdown.cancel();
  1421. }
  1422.  
  1423. public boolean cancelBorderCountdown() {
  1424. if (this.borderCountdown == null) return false;
  1425. return borderCountdown.cancel();
  1426. }
  1427.  
  1428. public boolean startBorderCountdown(int countLength, int newRadius) {
  1429. if ((this.borderCountdown == null || !this.borderCountdown.isActive()) && this.matchPhase == MatchPhase.MATCH) {
  1430. this.borderCountdown = new BorderCountdown(countLength, plugin, this, newRadius);
  1431. return true;
  1432. }
  1433. return false;
  1434. }
  1435.  
  1436. public boolean startPVPCountdown(int countLength, Boolean newValue) {
  1437. if ((this.pvpCountdown == null || !this.pvpCountdown.isActive()) && this.matchPhase == MatchPhase.MATCH) {
  1438. this.pvpCountdown = new PVPCountdown(countLength, plugin, this, newValue);
  1439. return true;
  1440. }
  1441. return false;
  1442. }
  1443.  
  1444. public boolean cancelPVPCountdown() {
  1445. if (this.pvpCountdown == null) return false;
  1446. return pvpCountdown.cancel();
  1447. }
  1448.  
  1449. public boolean startPermadayCountdown(int countLength, Boolean newValue) {
  1450. if ((this.permadayCountdown == null || !this.permadayCountdown.isActive()) && this.matchPhase == MatchPhase.MATCH) {
  1451. this.permadayCountdown = new PermadayCountdown(countLength, plugin, this, newValue);
  1452. return true;
  1453. }
  1454. return false;
  1455. }
  1456.  
  1457. public boolean cancelPermadayCountdown() {
  1458. if (this.permadayCountdown == null) return false;
  1459. return permadayCountdown.cancel();
  1460. }
  1461.  
  1462. public Collection<UhcTeam> getTeams() {
  1463. return uhcTeams.values();
  1464. }
  1465.  
  1466. public boolean clearTeams() {
  1467. if (matchPhase != MatchPhase.PRE_MATCH) return false;
  1468.  
  1469. this.uhcTeams.clear();
  1470. this.teamsInMatch.clear();
  1471. this.participantsInMatch.clear();
  1472. return true;
  1473. }
  1474.  
  1475.  
  1476.  
  1477. /**
  1478. * Modify the relevant recipes for UHC
  1479. */
  1480. public void setupModifiedRecipes() {
  1481. ItemStack goldenApple = new ItemStack(Material.GOLDEN_APPLE, 1, (short) 0);
  1482. ItemStack glisteringMelon = new ItemStack(Material.SPECKLED_MELON);
  1483.  
  1484. Iterator<Recipe> recipes = Bukkit.recipeIterator();
  1485. while(recipes.hasNext()) {
  1486. Recipe recipe = recipes.next();
  1487. // Find recipe for golden apple
  1488. if(recipe.getResult().equals(goldenApple) || recipe.getResult().equals(glisteringMelon))
  1489. recipes.remove();
  1490.  
  1491. }
  1492.  
  1493. ShapedRecipe goldenAppleRecipe = new ShapedRecipe(goldenApple);
  1494.  
  1495. goldenAppleRecipe.shape(new String[]{"GGG", "GAG", "GGG"});
  1496. goldenAppleRecipe.setIngredient('G', Material.GOLD_INGOT);
  1497. goldenAppleRecipe.setIngredient('A', Material.APPLE);
  1498.  
  1499. server.addRecipe(goldenAppleRecipe);
  1500.  
  1501. ShapelessRecipe glisteringMelonRecipe = new ShapelessRecipe(glisteringMelon);
  1502.  
  1503. glisteringMelonRecipe.addIngredient(Material.MELON);
  1504. glisteringMelonRecipe.addIngredient(Material.GOLD_BLOCK);
  1505.  
  1506. server.addRecipe(glisteringMelonRecipe);
  1507. }
  1508.  
  1509. public void createNewPOI(Location location, String name) {
  1510. addPOI(location, name);
  1511. config.saveMatchParameters();
  1512. }
  1513.  
  1514. public void addPOI(Location location, String name) {
  1515. uhcPOIs.add(new UhcPOI(location, name));
  1516. }
  1517.  
  1518. public void addPOI(String world, double x, double y, double z, String name) {
  1519. addPOI(new Location(server.getWorld(world), x, y, z), name);
  1520. }
  1521.  
  1522. public ArrayList<UhcPOI> getPOIs() {
  1523. return uhcPOIs;
  1524. }
  1525.  
  1526. public void clearPOIs() {
  1527. uhcPOIs.clear();
  1528. }
  1529.  
  1530. public ArrayList<UhcEvent> getEvents() {
  1531. return uhcEvents;
  1532. }
  1533.  
  1534. public void addEvent(UhcEvent event) {
  1535. uhcEvents.add(event);
  1536. }
  1537.  
  1538. public void clearEvents() {
  1539. uhcEvents.clear();
  1540. }
  1541.  
  1542.  
  1543. public String getPlayerStatusReport() {
  1544. String response = "";
  1545. if (config.isFFA()) {
  1546. Collection<UhcParticipant> allPlayers = getUhcParticipants();
  1547. response += allPlayers.size() + " players (" + countParticipantsInMatch() + " still alive):\n";
  1548.  
  1549. for (UhcParticipant up : allPlayers) {
  1550. String health;
  1551.  
  1552. Player p = server.getPlayerExact(up.getName());
  1553. if (up.isDead()) {
  1554. health = ChatColor.RED + "(dead)";
  1555. } else {
  1556. if (p != null)
  1557. health = ChatColor.GOLD + "(" + Double.toString(p.getHealth() / 2.0) + ")";
  1558. else
  1559. health = ChatColor.GRAY + "(offline)";
  1560. }
  1561. response += (up.isDead() ? ChatColor.RED : ChatColor.GREEN)
  1562. + " " + up.getName() + " " + health + "\n";
  1563. }
  1564.  
  1565. } else {
  1566. Collection<UhcTeam> allTeams = getTeams();
  1567. response = ChatColor.GOLD + "" + allTeams.size() + " teams (" + countTeamsInMatch() + " still alive):\n";
  1568.  
  1569. for (UhcTeam team : allTeams) {
  1570. response += (team.aliveCount()==0 ? ChatColor.RED + "[D] " : ChatColor.GREEN) + "" +
  1571. ChatColor.ITALIC + team.getName() + ChatColor.GRAY +
  1572. " [" + team.getIdentifier() + "]\n";
  1573. for (UhcParticipant up : team.getMembers()) {
  1574. String health;
  1575.  
  1576. Player p = server.getPlayerExact(up.getName());
  1577. if (up.isDead()) {
  1578. health = ChatColor.RED + "(dead)";
  1579. } else {
  1580. if (p != null)
  1581.  
  1582.  
  1583. health = ChatColor.GOLD + "(" + Double.toString(p.getHealth() / 2.0) + ")";
  1584. else
  1585. health = ChatColor.GRAY + "(offline)";
  1586. }
  1587. response += (up.isDead() ? ChatColor.RED : ChatColor.GREEN)
  1588. + " " + up.getName() + " " + health + "\n";
  1589. }
  1590. }
  1591. }
  1592.  
  1593.  
  1594. return response;
  1595. }
  1596.  
  1597.  
  1598. public Server getServer() { return server; }
  1599.  
  1600. public UhcPlayer getPlayer(String name) { return this.getPlayer(server.getOfflinePlayer(name)); }
  1601. public UhcPlayer getPlayer(OfflinePlayer p) {
  1602. if (p == null) return null;
  1603. UhcPlayer pl = allPlayers.get(p.getName().toLowerCase());
  1604. if (pl == null) {
  1605. pl = new UhcPlayer(p.getName().toLowerCase(), this);
  1606. allPlayers.put(p.getName().toLowerCase(), pl);
  1607. }
  1608. return pl;
  1609. }
  1610.  
  1611. public UhcPlayer getExistingPlayer(String name) { return this.getExistingPlayer(server.getOfflinePlayer(name)); }
  1612. public UhcPlayer getExistingPlayer(OfflinePlayer p) {
  1613. return allPlayers.get(p.getName().toLowerCase());
  1614. }
  1615.  
  1616. public ArrayList<UhcPlayer> getOnlinePlayers() {
  1617. ArrayList<UhcPlayer> ups = new ArrayList<UhcPlayer>();
  1618. for (Player p : server.getOnlinePlayers()) ups.add(getPlayer(p));
  1619. return ups;
  1620. }
  1621.  
  1622. public Calendar getMatchStartTime(){
  1623. return matchStartTime;
  1624. }
  1625.  
  1626. public ArrayList<UhcParticipant> getParticipants(){
  1627. return participantsInMatch;
  1628. }
  1629.  
  1630. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement