<?php

namespace bridge\utils\arena;

use pocketmine\level\Position;
use pocketmine\Player;

use pocketmine\math\Vector3;
use pocketmine\math\Vector2;

use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\DoubleTag;
use bridge\Mod_TopModule;

use pocketmine\event\entity\EntityDamageEvent;

use pocketmine\block\Block;
use pocketmine\item\Item;
use pocketmine\entity\Effect;
use pocketmine\item\enchantment\Enchantment;

use pocketmine\utils\Color;

use bridge\utils\Team;
use bridge\utils\Utils;
use bridge\Main;

class ArenaManager{
	
	const STAT_ESPERA = 0;
	const STAT_STATING = 1;
	const STAT_START = 2;
	const STAT_RUN = 3;
	
	const STAT_RESTART = 5;
	const STAT_GANHO = 6;
	
	private $players = [];
	
	public $stat = 0;
	
	private $time = 0;
	private $times = 0;
	
	public $plugin;
	private $nametag = [];
	
	public function __construct(Main $plugin, $data){
		$this->plugin = $plugin;
		$this->data = $data;
		$this->initMapa();
		$this->reset(false);
	}
	
	public function getUtils(){
		return (new Utils($this->plugin));
	}
	
	public function initMapa(){
		$utils = $this->getUtils();
		$map = $this->data["world"];
		if($utils->backupExists($map)){
			$this->resetMap();
			return true;
		}
		$utils->backupMap($map, $this->plugin->getDataFolder());
	}
	
	public function resetMap(){
		$utils = $this->getUtils();
		$map = $this->data["world"];
		$utils->resetMap($map);
	}
	
	public function getServer(){
		return $this->plugin->getServer();
	}
	
	public function getData(){
		return $this->data;
	}
	
	public function getPlayers(){
		return $this->players;
	}
	
	public function getConfig(){
		return $this->plugin->getConfig()->getAll();
	}
	
	public function getPos1($v = true){
		$data = $this->getData();
		if(isset($data["pos1"])){
			$dt = $data["pos1"];
			if(!$v){
				return new Vector2($dt["x"], $dt["z"]);
			}
			if(isset($data["world"])){
				$name = $data["world"];
				if($this->isLoad($name)){
					$level = $this->getServer()->getLevelByName($name);
					$pos = new Position($dt["x"], $dt["y"], $dt["z"], $level);
					return $pos;
				}
			}
		}
		return null;
	}
	
	public function getPos2($v = true){
		$data = $this->getData();
		if(isset($data["pos2"])){
			$dt = $data["pos2"];
			if(!$v){
				return new Vector2($dt["x"], $dt["z"]);
			}
			if(isset($data["world"])){
				$name = $data["world"];
				if($this->isLoad($name)){
					$level = $this->getServer()->getLevelByName($name);
					$pos = new Position($dt["x"], $dt["y"], $dt["z"], $level);
					return $pos;
				}
			}
		}
		return null;
	}
	
	public function getSpawn1(){
		$data = $this->getData();
		if(isset($data["spawn1"])){
			$dt = $data["spawn1"];
			if(isset($data["world"])){
				$name = $data["world"];
				if($this->isLoad($name)){
					$level = $this->getServer()->getLevelByName($name);
					$pos = new Position($dt["x"], $dt["y"], $dt["z"], $level);
					return $pos;
				}
			}
		}
		return null;
	}
	
	public function getSpawn2(){
		$data = $this->getData();
		if(isset($data["spawn2"])){
			$dt = $data["spawn2"];
			if(isset($data["world"])){
				$name = $data["world"];
				if($this->isLoad($name)){
					$level = $this->getServer()->getLevelByName($name);
					$pos = new Position($dt["x"], $dt["y"], $dt["z"], $level);
					return $pos;
				}
			}
		}
		return null;
	}
	
	public function getRespawn1($v = true){
		$data = $this->getData();
		if(isset($data["respawn1"])){
			$dt = $data["respawn1"];
			if(!$v){
				return new Vector2($dt["x"], $dt["z"]);
			}
			if(isset($data["world"])){
				$name = $data["world"];
				if($this->isLoad($name)){
					$level = $this->getServer()->getLevelByName($name);
					$pos = new Position($dt["x"], $dt["y"], $dt["z"], $level);
					return $pos;
				}
			}
		}
		return null;
	}
	
	public function getRespawn2($v = true){
		$data = $this->getData();
		if(isset($data["respawn2"])){
			$dt = $data["respawn2"];
			if(!$v){
				return new Vector2($dt["x"], $dt["z"]);
			}
			if(isset($data["world"])){
				$name = $data["world"];
				if($this->isLoad($name)){
					$level = $this->getServer()->getLevelByName($name);
					$pos = new Position($dt["x"], $dt["y"], $dt["z"], $level);
					return $pos;
				}
			}
		}
		return null;
	}
	
	public function getLevel(){
		$data = $this->getData();
		if(isset($data["world"])){
			$name = $data["world"];
			if($this->isLoad($name)){
				$level = $this->getServer()->getLevelByName($name);
				return $level;
			}
		}
		return null;
	}
	
	public function isTeamMode(){
		$data = $this->getData();
		if(isset($data["mode"])){
			if($data["mode"] == "team" or $data["mode"] == "squad"){
				return true;
			}
		}
		return false;
	}
	
	public function getSpawn(){
		$data = $this->getData();
		if(isset($data["local-de-espera"])){
			$dt = $data["local-de-espera"];
			if(!isset($dt["level"])){
				return null;
			}
			$pos = new Position($dt["x"], $dt["y"], $dt["z"]);
			if($this->isLoad($dt["level"])){
				$level = $this->getServer()->getLevelByName($dt["level"]);
				$pos->setLevel($level);
			} else {
				$this->broadcast("§c» §fМир §e" . $dt["level"] . "§fне существует!");
				return null;
			}
			return $pos;
		}
		return null;
	}
	
	public function isInArena($name){
		if($name instanceof Player){
			$name = $name->getName();
		}
		$name = strtolower($name);
		if(isset($this->players[$name])){
			return true;
		}
		return false;
	}
	
	public function getNecCount(){
		$data = $this->getData();
		if(isset($data["mode"])){
			switch($data["mode"]){
				case "solo":
				return 2;
				case "team":
				return 4;
				case "squad":
				return 8;
			}
		}
		return 2;
	}
	
	public function onRun($timer = null){
		$nec = $this->getNecCount();
		switch($this->stat){
			case self::STAT_ESPERA:
			$players = $this->getPlayers();
			if(count($players) >= $nec){
				$this->stat = self::STAT_STATING;
			} else {
				if(count($players) <= 0){
					return true;
				}
			}
			break;
			case self::STAT_STATING:
			$players = $this->getPlayers();
			if(count($players) < $nec){
				$this->stat = self::STAT_ESPERA;
				$this->time = 20;
			} else {
				$this->time--;
				$time = $this->time - 6;
				if($time <= 0){
					$this->setTeams();
					$this->stat = self::STAT_START;
					$this->broadcast("§a", 2);
					$this->replaceSpawn();
					$this->teleportPlayers($this->getPlayers());
				} else {
					$temp = $this->getTemp($time);
					$message = "§a$temp";
					$this->broadcast($message);
				}
			}
			break;
			case self::STAT_START:
			$this->time--;
			if($this->time <= 0){
				$this->stat = self::STAT_RUN;
				$this->startGame();
			} else {
				$this->broadcast("§a" . $this->time . "", 2);
				//$this->broadcast("§l                                             §7(§1TheBridge§7) §b(" . $this->data["mode"] . ")\n§f\n§f                                                          §9Синяя:§r§f " . $this->ponts["blue"] . "§fочков\n§8                                                          §cRed:§r§f " . $this->ponts["red"] . "§7 pontos\n§l§6                                " . $this->time . "§r§8\n§8                                                         §fBestMC.desire.host\n§8\n§8\n§8\n§8", 2);
			}
			return true;
			break;
			case self::STAT_RUN:
			$level = $this->getLevel();
			if(!is_null($level)){
				foreach($level->getPlayers() as $p){
				    $r = str_repeat(" ", 45);
				    $date = date("d.m.y");
				    $ping = $p->getPing();
					$p->sendTip("{$r}§cThe§9Bridge\n{$r}§7{$date}\n\n{$r}§cRed:§e " . $this->ponts["red"] . "\n{$r}§9Blue:§e " . $this->ponts["blue"] . "\n\n{$r}§fPing: §e{$ping}ms");
				}
			}
			$this->initPlayers();
			break;
			case self::STAT_RESTART:
			$this->time--;
			if($this->time <= 0){
				$this->stat = self::STAT_RUN;
				$this->startGame();
			} else {
				$this->broadcast("§a" . $this->time . "", 2);
			}
			return true;
			break;
			case self::STAT_GANHO:
			$this->segs--;
			$this->broadcast($this->lastMessage, 2);
			if($this->segs <= 0){
				$players = $this->getPlayers();
				foreach($players as $name => $pl){
					$p = $this->plugin->getServer()->getPlayerExact($name);
					if(is_null($p)){
						unset($this->players[$name]);
						continue;
					}
					$this->quit($p);
				}
				$this->reset(true);
			}
			break;
		}
	}
	
	private $segs = 10;
	
	
	public function getCount(){
		$count = count($this->players);
		return $count;
	}
	
	private $base = [
	"blue" => 0,
	"red" => 0
	];
	
	private $ponts = [];
	private $team = null;
	
	public function getTeamData(){
		if(is_null($this->team)){
			$nec = $this->getNecCount() / 2;
			$this->team = new Team($nec);
		}
		return $this->team;
	}
	
	private function setRadomTeam($name){
		$data = $this->getTeamData();
		
		if(!$data->isInTeam($name)){
			if($this->setTeam("blue", $name)){
			} elseif($this->setTeam("red", $name)){
			}
			return true;
		}
		return false;
	}
	
	public function setTeam($team = "blue", $name){
		$data = $this->getTeamData();
		
		if($this->getTeam($name) == $team){
			return true;
		}
		if($data->addPlayerTeam($name, $team)){
			return true;
		}
		return false;
	}
	
	private function setTeams(){
		$data = $this->getTeamData();
		$players = $this->getPlayers();
		
		if(count($players) <= 0){
			$this->reset();
			return true;
		}
		foreach($players as $name => $p){
			if(!$data->isInTeam($name)){
				if($this->setTeam("blue", $name)){
				} elseif($this->setTeam("red", $name)){
				}
			}
		}
	}
	
	public function getTeam($name){
		$data = $this->getTeamData();
		return $data->getPlayerTeam($name);
	}
	
	public function isTeam($p1, $p2){
		$data = $this->getTeamData();
		if($data->isTeam($p1, $p2)){
			return true;
		}
		return false;
	}
	
	public function reset($value = true){
		$this->players = [];
		
		$this->time = 20;
		$this->segs = 10;
		$this->winner = "blue";
		$this->stat = self::STAT_ESPERA;
		
		$this->getTeamData()->reset();
		$this->nametag = [];
		$this->ponts = $this->base;
		
		if($value){
			$this->resetMap();
		}
	}
	
	public function close(){
		$players = $this->getPlayers();
		if(count($players) <= 0){
			$this->reset(true);
			return true;
		}
		foreach($players as $name => $pl){
			$p = $this->plugin->getServer()->getPlayerExact($name);
			if(!is_null($p)){
				$this->quit($p);
			} else {
				unset($this->players[$name]);
			}
		}
		$this->reset(true);
		$this->plugin->MOD_top_module->reloadData();
	}
	
	private $lastMessage = "";
	
	public function broadcast($message, $type = 1){
		$players = $this->getPlayers();
		if(count($players) <= 0){
			if($message !== 2){
				$this->reset();
			}
			return true;
		}
		foreach($players as $name => $pl){
			$p = $this->plugin->getServer()->getPlayerExact($name);
			if(is_null($p)){
				unset($this->players[$name]);
				continue;
			} elseif(!$this->isInArena($p)){
				unset($this->players[$name]);
				continue;
			}
			/*if($message == 2){
				$team = $this->team[$name] == "blue" ? "§9Синие§r" : "§cКрасные§r";
				$p->sendTip("§l                                            §7(§1TheBridge§7)§r§b (" . $this->data["mode"] . ")\n§8\n§8                                                          §eJogadores:§r§f " . count($this->players) . "§8\n§8                                                          §eTime: $team §r§8\n§8\n§8                                                         §fBestMC.desire.host\n§8\n§8\n§8\n§8", 2);
				continue;
			}*/
			$this->lastMessage = $message;
			switch($type){
				case 1:
				$p->sendPopup($message);
				break;
				case 2:
				$p->sendTip($message);
				break;
				case 3:
				$p->sendMessage($message);
				break;
			}
		}
	}
	
	private $custons = [
	"§eSplinter" => "bridge.splinter",
	"§bDestroyer" => "bridge.destroyer",
	"§dKiller" => "bridge.killer",
	"§aTank" => "bridge.tank",
	"§6Bowman" => "bridge.bowman"
	];
	
	private $ids = [
	"bridge.splinter" => "373:14",
	"bridge.destroyer" => "278:0",
	"bridge.killer" => "276:0",
	"bridge.tank" => "311:0",
	"bridge.bowman" => "261:0"
	];
	
	public function useHab($item, $p){
		$name = strtolower($p->getName());
		$custom = $item->getCustomName();
		
		$inv = $p->getInventory();
		
		if($custom == "§cBack"){
			$inv->clearAll();
			$inv->setItem(1, Item::get(351, 12, 1)->setCustomName("§9Blue"));
			$inv->setItem(2, Item::get(351, 1, 1)->setCustomName("§cRed"));
			$inv->setItem(7, Item::get(355, 0, 1)->setCustomName("§cLeave"));
			return true;
		}
		if($custom == "§bPerks"){
			$inv->clearAll();
			$slot = 0;
			foreach($this->custons as $name => $perm){
				if($p->hasPermission($perm)){
					if(isset($this->ids[$perm])){
						$dt = explode(":", $this->ids[$perm]);
						$inv->setItem($slot, Item::get($dt[0], $dt[1], 1)->setCustomName($name));
					} else {
						$inv->setItem($slot, Item::get(340, 0, 1)->setCustomName($name));
					}
				} else {
					$inv->setItem($slot, Item::get(351, 1, 1)->setCustomName($name));
				}
				$slot++;
			}
			$inv->setItem(7, Item::get(262, 0, 1)->setCustomName("§cBack"));
			return true;
		}
		if(isset($this->custons[$custom])){
			$perm = $this->custons[$custom];
			if(!$p->hasPermission($perm)){
				return true;
			}
			$hab = strtolower(str_replace("bridge.", "", $perm));
			
			if(isset($this->skills[$name][0])){
				$hab1 = $this->skills[$name][0];
				if($hab1 == $hab){
					unset($this->skills[$name][0]);
					return true;
				}
				if($p->hasPermission("bridge.duple.hab")){
					if(isset($this->skills[$name][1])){
						$hab2 = $this->skills[$name][1];
						if($hab2 == $hab){
							unset($this->skills[$name][1]);
							return true;
						}
					} else {
						$this->skills[$name][0] = $hab;
						return true;
					}
				} else {
					return true;
				}
			} else {
				$this->skills[$name][0] = $hab;
				return true;
			}
		}
		return false;
	}
	
	private $skills = [];
	
	public function getHabs($name){
		if($name instanceof Player){
			$name = $name->getName();
		}
		$name = strtolower($name);
		if(isset($this->skills[$name])){
			return $this->skills[$name];
		}
		return [];
	}
	
	public function hasHab($name, $hab = "Splinter"){
		if($name instanceof Player){
			$name = $name->getName();
		}
		$name = strtolower($name);
		$hab = strtolower($hab);
		
		if(isset($this->skills[$name])){
			$data = $this->skills[$name];
			if(in_array($hab, $data)){
				return true;
			}
		}
		return false;
	}
	
	public function initPlayers(){
		$nec = $this->getNecCount() / 2;
		foreach($this->players as $name => $pl){
			$p = $this->plugin->getServer()->getPlayerExact($name);
			if(is_null($p)){
				unset($this->players[$name]);
				continue;
			} elseif(!$this->isInArena($p)){
				unset($this->players[$name]);
				continue;
			}
		}
		
		$count = count($this->players);
		if($count <= 0){
			$this->reset(true);
			return false;
		} elseif($count <= $nec){
			$value = false;
			if($this->isTeamMode()){
				$data = $this->players;
				if($count <= 1){
					$value = true;
				} elseif($this->isTeam(array_shift($data), array_shift($data))){
					$value = true;
				}
			} else {
				$value = true;
			}
			if($value){
				$data = $this->players;
				$team = $this->getTeam(array_shift($data));
				
				$msg2 = "§cRED WINS!\n\n\n\n";
				switch($team){
					case "blue":
					$msg2 = "§9BLUE WINS!\n\n\n\n";
				}
				$players = $this->getPlayers();
				foreach($players as $name => $pl){
					$p = $this->plugin->getServer()->getPlayerExact($name);
					if(is_null($p)){
						unset($this->players[$name]);
						continue;
					}
					$this->respawnPlayer($p, false);
				}
				$this->broadcast("$msg2", 2);
				$this->segs = 10;
				$this->stat = self::STAT_GANHO;
				$this->plugin->MOD_top_module->onWin($team);
				return true;
			}
		}
	}
	
	public function startGame($value = true){
		$this->removeY($this->getSpawn1(), true, null, 3);
		$this->removeY($this->getSpawn2(), true, null, 3);
	}
	
	public function replaceSpawn($value = true){
		$this->removeY($this->getSpawn1(), false);
		$this->removeY($this->getSpawn2(), false);
	}
	
	public function removeY($pos, $v = true, $dis = null, $ad = 0){
		$level = $this->getLevel();
		if(is_null($dis)){
			$dis = $this->getNecCount();
			$dis = $dis > 4 ? 4 : $dis;
		}
		$yy = $v ? 3 : 5;
		$yy += $ad;
		for($x = $pos->x - $dis; $x <= $pos->x + $dis; $x++){
			for($y = $pos->y + $yy; $y >= $pos->y - 1; $y--){
				for($z = $pos->z + $dis; $z >= $pos->z - $dis; $z--){
					if($v == true){
						$level->setBlock(new Vector3($x, $y, $z), Block::get(0));
					} else {
						$level->setBlock(new Vector3($x, $y, $z), Block::get(20));
					}
				}
			}
		}
		if(!$v){
			$this->removeY($pos->add(0, 1), true, $dis - 1);
		}
	}
	
	public function teleportPlayers($players){
		$level = $this->getLevel();
		
		foreach($players as $name => $pl){
			$p = $this->getServer()->getPlayerExact($name);
			if(is_null($p)){
				unset($this->players[$name]);
				continue;
			}
			
			$named = "§cRed§f " . $p->getName();
			$pos = $this->getSpawn2();
			
			$team = $this->getTeam($name);
			
			switch($team){
				case "blue":
				$named = "§9" . $p->getName();
				$pos = $this->getSpawn1();
				break;
				case "red":
				$named = "§c" . $p->getName();
				$pos = $this->getSpawn2();
				break;
			}
			if(!isset($this->nametag[$name])){
				$this->nametag[$name] = $p->getNameTag();
			}
			
			$p->setNameTag($named);
			$this->addItens($p);
			
			$p->teleport($pos);
		}
	}
	
	public function quit(Player $player, $msg = true){
		$name = strtolower($player->getName());
		if(!$this->isInArena($player)){
			return false;
		}
		$player->removeAllEffects();
		$player->setHealth($player->getMaxHealth());
		$player->setFood(20);
		
		$this->getTeamData()->removePlayerTeam($name);
		
	
		
		if(isset($this->nametag[$name])){
			$player->setNameTag($this->nametag[$name]);
			unset($this->nametag[$name]);
		}
		$level = $this->getServer()->getDefaultLevel();
		
		unset($this->players[$name]);
		if($msg){
			$player->teleport($level->getSafeSpawn());
		}
	}
	
	public function join(Player $player){
		$nec = $this->getNecCount();
		if($this->stat == self::STAT_ESPERA){
			if(count($this->players) >= $nec){
				return false;
			}
		} elseif($this->stat < 2){
			if(count($this->players) >= $nec){
				return false;
			}
			
		} else {
			return false;
		}
		$player->setGamemode(Player::SURVIVAL);
		$player->removeAllEffects();
		$player->setHealth($player->getMaxHealth());
		$player->setFood(20);
		$player->setAllowFlight(false);
		
		/**
		 * add item in STAT_RUN
		 *
		 * $inv = $player->getInventory();
		 *
		 * $inv->clearAll();
		 * $inv->setItem(0, Item::get(44, 0, 1));
		 */
		 
		 $inv = $player->getInventory();
		 $inv->clearAll();
		 
		 $inv->setItem(1, Item::get(351, 12, 1)->setCustomName("§9Blue"));
		 $inv->setItem(2, Item::get(351, 1, 1)->setCustomName("§cRed"));
		 $inv->setItem(7, Item::get(355, 0, 1)->setCustomName("§cLeave"));
		 $spawn = $this->getSpawn();
		 if(!is_null($spawn)){
		 	$player->teleport($spawn);
		 }
		
		$name = strtolower($player->getName());
		$this->players[$name] = $player;
		
		$this->setRadomTeam($name);
		return true;
	}
	
	
	public function respawnPlayer($p, $v = true){
		$name = strtolower($p->getName());
		$this->addItens($p, $v);
		
		$team = $this->getTeam($name);
		if(!is_null($team)){
			switch($team){
				case "blue":
				$pos = $this->getRespawn1();
				$p->teleport($pos);
				break;
				case "red":
				$pos = $this->getRespawn2();
				$p->teleport($pos);
				break;
			}
		}
	}
	
	public function addItens($p, $v = true){
		
		$p->setGamemode(Player::SURVIVAL);
		$p->setHealth($p->getMaxHealth());
		$p->setFood(20);
		
		if(!$v){
			$p->removeAllEffects();
			$inv = $p->getInventory();
			$inv->clearAll();
			
			$inv->setItem(7, Item::get(355, 0, 1)->setCustomName("§cLeave"));
			$this->plugin->MOD_top_module->onWin($p);
			return true;
		}
		
		$name = strtolower($p->getName());
		$color = Color::getDyeColor(1);
		$damage = 14;
		
		$team = $this->getTeam($name);
		if(!is_null($team)){
			switch($team){
				case "blue":
				$color = Color::getDyeColor(4);
				$damage = 11;
				break;
				case "red":
				$color = Color::getDyeColor(1);
				$damage = 14;
				break;
			}
		}
		$inv = $p->getInventory();
		$inv->clearAll();
		
		$esp = Item::get(267, 0, 1);
		if($this->hasHab($p, "killer")){
			$ench = Enchantment::getEnchantment(9);
			$ench->setLevel(1);
			
			$esp->addEnchantment($ench);
		}
		$pic = Item::get(278, 0, 1);
		if($this->hasHab($p, "destroyer")){
			$ench = Enchantment::getEnchantment(15);
			$ench->setLevel(5);
			
			$pic->addEnchantment($ench);
		}
		$arco = Item::get(261, 0, 1);
		$flecha = Item::get(262, 0, 8);
		$food = Item::get(364, 0, 5);
		$food2 = Item::get(322, 0, 2);
		$block = Item::get(159, $damage, 64);
		
		$inv->setItem(0, $esp);
		$inv->setItem(1, $pic);
		$inv->setItem(2, $arco);
		
		$inv->setItem(3, $block);
		$inv->setItem(4, $block);
		$inv->setItem(6, $food2);
		$inv->setItem(7, $food);
		$inv->setItem(32, $flecha);
		
		$cap = Item::get(298, 0, 1);
		$cap->setCustomColor($color);
		
		$peit = Item::get(299, 0, 1);
		$peit->setCustomColor($color);
		if($this->hasHab($p, "tank")){
			$peit = Item::get(311, 0, 1);
		}
		
		$calc = Item::get(300, 0, 1);
		$calc->setCustomColor($color);
		
		$bot = Item::get(301, 0, 1);
		$bot->setCustomColor($color);
		
		$inv->setHelmet($cap);
		$inv->setChestplate($peit);
		$inv->setLeggings($calc);
		$inv->setBoots($bot);
	}
	
	public function getPontPos($p, $v = true){
		$name = strtolower($p->getName());
		$team = $this->getTeam($name);
		
		if(!is_null($team)){
			switch($team){
				case "blue":
				if(!$v){
					return $this->getPos1();
				}
				$pos = $this->getPos2();
				return $pos;
				case "red":
				if(!$v){
					return $this->getPos2();
				}
				$pos = $this->getPos1();
				return $pos;
			}
		}
	}
	
	public function addPont($p){
		$name = strtolower($p->getName());
		
		$team = $this->getTeam($name);
		if(!is_null($team)){
			if(isset($this->ponts[$team])){
				if($this->ponts[$team] >= 5){
					return true;
				}
				$this->ponts[$team]++;
			}
			$msg = "§8(§9T§cB§8) §c".$p->getName()." §fscored§f!";
			$msg2 = "§cRED WINS!";
			switch($team){
				case "blue":
				$msg = "§8(§9T§cB§8) §9".$p->getName()." §fscored§f!";
				$msg2 = "§9BLUE WINS!";
			}
			$this->broadcast("$msg", 3);
			if($this->ponts[$team] >= 5){
				$players = $this->getPlayers();
				foreach($players as $name => $pl){
					$p = $this->plugin->getServer()->getPlayerExact($name);
					if(is_null($p)){
						unset($this->players[$name]);
						continue;
					}
					$this->respawnPlayer($p, false);
				}
				$this->broadcast("$msg2", 2);
				$this->segs = 10;
				$this->stat = self::STAT_GANHO;
				$this->plugin->MOD_top_module->onWin($team->getPlayer());
                $wins = $this->plugin->getServer()->getPluginManager()->getPlugin("WinsSystem");

$wins->bridgeWins($team->getPlayer());
				return true;
			}
		}
		$this->replaceSpawn();
		$this->teleportPlayers($this->getPlayers());
		foreach($this->players as $name => $p){
			if($this->getTeam($p) == $team){
				if($this->hasHab($p, "splinter")){
					$eff = Effect::getEffect(1);
					$eff->setDuration(80*20);
					$eff->setAmplifier(1);
					
					$p->addEffect($eff);
				}
			}
		}
		
		$this->time = 6;
		$this->stat = self::STAT_RESTART;
	}
	
	public function getPont($team = "blue"){
		if(!isset($this->ponts[$team])){
			return 0;
		}
		return $this->ponts[$team];
	}
	
	public function getTemp($time){
		$seg = (int)($time % 60);
		$time /= 60;
		$min = (int)($time % 60);
		$time /= 60;
		$hora = (int)($time % 24);
		if($seg < 10){
			$seg = "0" . $seg;
		}
		if($min < 10){
			$min = "0" . $min;
		}
		if($hora < 10){
			$hora = "0" . $hora;
		}
		return "$min:$seg";
	}
	
	public function isLoad($world){
		if($this->getServer()->isLevelLoaded($world)){
			return true;
		}
		if(!$this->getServer()->isLevelGenerated($world)){
			return false;
		}
		$this->getServer()->loadLevel($world);
		return $this->getServer()->isLevelLoaded($world);
	}
}