content: package com.rs2.game.content.minigames;
  
  import java.util.HashMap;
  
  import com.rs2.GameEngine;
  import com.rs2.game.content.combat.prayer.PrayerDrain;
  import com.rs2.game.npcs.Npc;
  import com.rs2.game.npcs.NpcHandler;
  import com.rs2.game.players.Player;
  import com.rs2.util.Misc;
  
  /**
   * @author Harlan Credits to Sanity
   */
  
  public class PestControl {
  
  	/**
  	 * /** how long before were put into the game from lobby
  	 */
  	private static final int WAIT_TIMER = 60;
  	/**
  	 * How many players we need to start a game
  	 */
  	private final static int PLAYERS_REQUIRED = 1;
  	/**
  	 * Hashmap for the players in lobby
  	 */
  	public static HashMap<Player, Integer> waitingBoat = new HashMap<Player, Integer>();
  	private static HashMap<Player, Integer> gamePlayers = new HashMap<Player, Integer>();
  
  	private static int gameTimer = -1;
  	private static int waitTimer = 60;
  	public static boolean gameStarted = false;
  	private int properTimer = 0;
  	public static int KNIGHTS_HEALTH = -1;
  
  	/**
  	 * Array used for storing the portals health
  	 */
  	public static int[] portalHealth = { 200, 200, 200, 200 };
  	public static int[] portals = { 3777, 3778, 3779, 3780 };
  	/**
  	 * array used for storing the npcs used in the minigame
  	 * 
  	 * @order npcId, xSpawn, ySpawn, health
  	 */
  	
  	public int shifter = 3732 + Misc.random(9);
  	public int brawler = 3772 + Misc.random(4);
  	public int defiler = 3762 + Misc.random(9);
  	public int ravager = 3742 + Misc.random(4);
  	public int torcher = 3752 + Misc.random(7);
  	public int splater = 3727 + Misc.random(4);
  	
  
  	private final int[][] pcNPCData = { { 3777, 2628, 2591 }, // portal
  			{ 3778, 2680, 2588 }, // portal
  			{ 3779, 2669, 2570 }, // portal
  			{ 3780, 2645, 2569 }, // portal
  			{ 3782, 2656, 2592 }, // knight
  	};
  	
  	private final int[][] voidMonsterData = {
  			{ shifter, 2660 + Misc.random(4), 2592 + Misc.random(4) },
  			{ brawler, 2663 + Misc.random(4), 2575 + Misc.random(4) },
  			{ defiler, 2656 + Misc.random(4), 2572 + Misc.random(4) },
  			{ ravager, 2664 + Misc.random(4), 2574 + Misc.random(4) },
  			{ torcher, 2656 + Misc.random(4), 2595 + Misc.random(4) },
  			{ ravager, 2634 + Misc.random(4), 2596 + Misc.random(4) },
  			{ brawler, 2638 + Misc.random(4), 2588 + Misc.random(4) },
  			{ shifter, 2637 + Misc.random(4), 2598 + Misc.random(4) },
  			{ ravager, 2677 + Misc.random(4), 2579 + Misc.random(4) },
  			{ defiler, 2673 + Misc.random(4), 2584 + Misc.random(4) },
  			{ defiler, 2673 + Misc.random(4), 2584 + Misc.random(4) },
  			{ defiler, 2675 + Misc.random(4), 2591 + Misc.random(4) },
  			{ splater, 2644 + Misc.random(4), 2575 + Misc.random(4) },
  			{ splater, 2633 + Misc.random(4), 2595 + Misc.random(4) }};
  
  	public void process() {
  		try {
  			if (properTimer > 0) {
  				properTimer--;
  				return;
  			} else {
  				properTimer = 1;
  			}
  			waitBoat();
  			if (waitTimer > 0) {
  				waitTimer--;
  			} else if (waitTimer == 0) {
  				startGame();
  			}
  			if (KNIGHTS_HEALTH == 0) {
  				endGame(false);
  			}
  			if (gameStarted && playersInGame() < 1) {
  				endGame(false);
  			}
  			if (gameTimer > 0 && gameStarted) {
  				gameTimer--;
  				setGameInterface();
  				if (allPortalsDead() || allPortalsDead3()) {
  					endGame(true);
  				}
  			} else if (gameTimer <= 0 && gameStarted) {
  				endGame(false);
  			}
  		} catch (RuntimeException e) {
  			System.out.println("Failed to set process");
  			e.printStackTrace();
  		}
  	}
  
  	/**
  	 * Method we use for removing a player from the pc game
  	 * 
  	 * @param player
  	 *            The Player.
  	 */
  	public static void removePlayerGame(Player player) {
  		if (gamePlayers.containsKey(player)) {
  			player.getPlayerAssistant().movePlayer(2657, 2639, 0);
  			gamePlayers.remove(player);
  		}
  	}
  
  	private static void waitBoat() {
  		for (final Player c : waitingBoat.keySet()) {
  			if (c != null) {
  				if (gameStarted && isInPcBoat(c)) {
  					c.getPacketSender().sendMessage("Next Departure: " + (waitTimer + gameTimer) / 60 + " minutes");
  				} else {
  					c.getPacketSender().sendMessage("Next Departure: " + waitTimer + " seconds.");
  				}
  			}
  		}
  	}
  
  	public static void setGameInterface() {
  		for (final Player player : gamePlayers.keySet()) {
  			if (player != null) {
  				if (gameTimer > 60) {
  					player.getPacketSender().sendMessage("Time remaining: " + gameTimer / 60 + " minutes");
  				} else if (gameTimer < 60) {
  					player.getPacketSender().sendMessage("Time remaining: " + gameTimer + " seconds");
  				}
  				player.getPacketSender().sendMessage("The knights current health is " + KNIGHTS_HEALTH + ".");
  				player.getPacketSender().sendMessage("Your current pc damage is " + player.pcDamage + ".");
  			}
  		}
  	}
  
  	/***
  	 * Moving players to arena if there's enough players
  	 */
  	private void startGame() {
  		if (playersInBoat() < PLAYERS_REQUIRED) {
  			waitTimer = WAIT_TIMER;
  			return;
  		}
  		for (int i = 0; i < portalHealth.length; i++) {
  			portalHealth[i] = 200;
  		}
  		gameStarted = true;
  		gameTimer = 400;
  		KNIGHTS_HEALTH = 250;
  		waitTimer = -1;
  		spawnNPC();
  		setGameInterface();
  		for (Player player : waitingBoat.keySet()) {
  			int team = waitingBoat.get(player);
  			if (player == null) {
  				continue;
  			}
  			player.getPlayerAssistant().movePlayer(2656 + Misc.random3(3), 2614 - Misc.random3(4), 0);
  			player.getDialogueHandler().sendDialogues(599, 3790);
  			player.getPacketSender().sendMessage("The Pest Control game has begun!");
  			player.npcCanAttack = true;
  			gamePlayers.put(player, team);
  		}
  		waitingBoat.clear();
  	}
  
  	/**
  	 * Checks how many players are in the waiting lobby
  	 * 
  	 * @return players waiting
  	 */
  	private static int playersInBoat() {
  		int players = 0;
  		for (Player player : waitingBoat.keySet()) {
  			if (player != null) {
  				players++;
  			}
  			if (player == null) {
  				players--;
  			}
  		}
  		return players;
  	}
  
  	/**
  	 * Checks how many players are in the game
  	 * @return players in the game
  	 */
  	private int playersInGame() {
  		int players = 0;
  		for (Player player : gamePlayers.keySet()) {
  			if (player != null) {
  				players++;
  			}
  			if (player == null) {
  				players--;
  			}
  		}
  		return players;
  	}
  
  	private void endGame(boolean won) {
  		for (Player player : gamePlayers.keySet()) {
  			if (player == null) {
  				continue;
  			}
  			player.getPlayerAssistant().movePlayer(2657, 2639, 0);
  			if (won && player.pcDamage > 50) {
  				player.getDialogueHandler().sendDialogues(598, 3790);
  				int POINT_REWARD = 4;
  				player.getPacketSender().sendMessage(
  						"You have won the pest control game and have been awarded "
  								+ POINT_REWARD + " Pest Control points.");
  				player.pcPoints += POINT_REWARD;
  				player.getItemAssistant().addItem(995, player.combatLevel * 10);
  			} else if (won) {
  				player.getDialogueHandler().sendDialogues(596, 3790);
  				int POINT_REWARD2 = 2;
  				player.pcPoints += POINT_REWARD2;
  				player.getPacketSender().sendMessage(
  						"The void knights notice your lack of zeal. You only gain "
  								+ POINT_REWARD2 + " points.");
  			} else {
  				player.getDialogueHandler().sendDialogues(597, 3790);
  				player.getPacketSender()
  						.sendMessage(
  								"You failed to kill all the portals in 3 minutes and have not been awarded points.");
  			}
  		}
  		cleanUpPlayer();
  		cleanUp();
  	}
  
  	/**
  	 * Resets the game variables and map
  	 */
  	private void cleanUp() {
  		gameTimer = -1;
  		KNIGHTS_HEALTH = -1;
  		waitTimer = WAIT_TIMER;
  		gameStarted = false;
  		gamePlayers.clear();
  		/*
  		 * Removes the npcs from the game if any left over for whatever reason
  		 */
  		for (int[] aPcNPCData : pcNPCData) {
  			for (int j = 0; j < NpcHandler.npcs.length; j++) {
  				if (NpcHandler.npcs[j] != null) {
  					if (NpcHandler.npcs[j].npcType == aPcNPCData[0]) {
  						NpcHandler.npcs[j] = null;
  					}
  				}
  			}
  		}
  		for (int[] aPcNPCData : voidMonsterData) {
  			for (int j = 0; j < NpcHandler.npcs.length; j++) {
  				if (NpcHandler.npcs[j] != null) {
  					if (NpcHandler.npcs[j].npcType == aPcNPCData[0]) {
  						NpcHandler.npcs[j] = null;
  					}
  				}
  			}
  		}
  	}
  
  	/**
  	 * Cleans the player of any damage, loss they may of received
  	 */
  	private void cleanUpPlayer() {
  		for (Player player : gamePlayers.keySet()) {
  			player.poisonDamage = 0;
  			PrayerDrain.resetPrayers(player);
  			for (int i = 0; i < 24; i++) {
  				player.playerLevel[i] = player.getPlayerAssistant().getLevelForXP(player.playerXP[i]);
  				player.getPlayerAssistant().refreshSkill(i);
  			}
  			player.specAmount = 10;
  			player.pcDamage = 0;
  			player.getItemAssistant().addSpecialBar(player.playerEquipment[player.playerWeapon]);
  		}
  	}
  
  	/**
  	 * Checks if the portals are dead
  	 * 
  	 * @return players dead
  	 */
  	private static boolean allPortalsDead() {
  		int count = 0;
  		for (int aPortalHealth : portalHealth) {
  			if (aPortalHealth <= 0) {
  				count++;
  				// System.out.println("Portal Health++" + count);
  			}
  		}
  		return count >= 4;
  	}
  
  	public boolean allPortalsDead3() {
  		int count = 0;
  		for (Npc npc : NpcHandler.npcs) {
  			if (npc != null) {
  				if (npc.npcType > 3777 && npc.npcType < 3780) {
  					if (npc.needRespawn) {
  						count++;
  					}
  				}
  			}
  		}
  		return count >= 4;
  	}
  
  	/**
  	 * Moves a player out of the waiting boat
  	 * 
  	 * @param player
  	 *            Client c
  	 */
  	public static void leaveWaitingBoat(Player player) {
  		if (waitingBoat.containsKey(player)) {
  			waitingBoat.remove(player);
  			player.getPlayerAssistant().movePlayer(2657, 2639, 0);
  		}
  	}
  
  	/**
  	 * Moves a player into the hash and into the lobby
  	 * 
  	 * @param player
  	 *            The player
  	 */
  	public static void addToWaitRoom(Player player) {
  		if (player != null && player.combatLevel > 39) {
  			waitingBoat.put(player, 1);
  			player.getPacketSender().sendMessage(
  					"You have joined the Pest Control boat.");
  			player.getPacketSender().sendMessage(
  					"You currently have " + player.pcPoints
  							+ " Pest Control Points.");
  			player.getPacketSender().sendMessage(
  					"There are currently " + playersInBoat()
  							+ " players ready in the boat.");
  			player.getPacketSender().sendMessage(
  					"Players needed: " + PLAYERS_REQUIRED + " to 25 players.");
  			player.getPlayerAssistant().movePlayer(2661, 2639, 0);
  			waitBoat();
  		} else if (player.combatLevel < 40) {
  			player.getPacketSender().sendMessage("You need 40 combat to play pest control.");
  		}
  	}
  
  	/**
  	 * Checks if a player is in the game
  	 * 
  	 * @param player
  	 *            The player
  	 * @return return
  	 */
  	public static boolean isInGame(Player player) {
  		return gamePlayers.containsKey(player);
  	}
  
  	/**
  	 * Checks if a player is in the pc boat (lobby)
  	 * 
  	 * @param player
  	 *            The player
  	 * @return return
  	 */
  	public static boolean isInPcBoat(Player player) {
  		return waitingBoat.containsKey(player);
  	}
  
  	public static boolean npcIsPCMonster(int npcType) {
  		return (npcType >= 3727 && npcType <= 3776);
  	}
  	
  	public static boolean isPCPortal(int npcType) {
  		return (npcType >= 3777 && npcType <= 3780);
  	}
  
  	private void spawnNPC() {
  		//npcid, npcx, npcy, heightlevel, walking type, hp, att, def
  		for (int[] aPcNPCData : pcNPCData) {
  			GameEngine.npcHandler.spawnNpc2(aPcNPCData[0], aPcNPCData[1], aPcNPCData[2], 0, 0, 200, 0, 0, playersInGame() * 200, false);
  		}
  		for (int[] voidMonsters : voidMonsterData) {
  			//GameEngine.npcHandler.spawnNpc2(voidMonsters[0], voidMonsters[1], voidMonsters[2], 0, 1, voidMonsters[NpcHandler.getNpcListHP(voidMonsters[0])], NpcHandler.getNpcListCombat(voidMonsters[0])/10, NpcHandler.getNpcListCombat(voidMonsters[0]), playersInGame() * 200);
  			GameEngine.npcHandler.spawnNpc2(voidMonsters[0], voidMonsters[1], voidMonsters[2], 0, 1, 50, 20, 75, 50, true);
  		}
  	}
  }
  