Location: PHPKode > projects > PhpBlock > A9.8/modules/dungeon/dungeonserver.class.php
<?php
include_once $PATH_TO_CODE."/script/fonction.php";
include_once $PATH_TO_CODE."/script/zone.class.php";

include_once $PATH_TO_CODE."/script/log.class.php";
include_once $PATH_TO_CODE."/script/server.class.php";


class DungeonServer {
	private static $instance=false;
	private static $BLOCK_IS_SECURE=1;
	private static $BLOCK_IS_UNSECURE=2;

	private $serverBlockIdList;

	public function getInstance() {
		if(!DungeonServer::$instance) {
			DungeonServer::$instance = new DungeonServer();
		}
		return DungeonServer::$instance;
	}
	private function getLastHappyHomeId($parPlayerType) {
		$locHappyHomeId = Server::getInstance()->getValue(Server::$SERVER_TYPE1_CREATE_PLAYER,
		Server::$SERVER_TYPE2_HAPPY_HOME_PLAYER_TYPE_BASE+$parPlayerType);
		if(Block::exist($locHappyHomeId)) {
			return $locHappyHomeId;
		} else {
			return false;
		}
	}
	private function setLastHappyHome($parPlayerType, $parBlockId) {
		Server::getInstance()->upsertValue(Server::$SERVER_TYPE1_CREATE_PLAYER,
		Server::$SERVER_TYPE2_HAPPY_HOME_PLAYER_TYPE_BASE+$parPlayerType, $parBlockId);
	}
	public function getAnHappyHomeNearBlockId($parPlayerType, $parBlockId) {
		$this->initBlockList($parPlayerType);
		for($i = 0; $i < 4; $i++) {
			$locBlockIdList = Block::getStaticBlockIdsFromXYZ($parBlockId, $i, $i, ($i == 0 ? 0 : 1));
			foreach($locBlockIdList as $locBlockId) {
				if($this->isAnHappyHome($parPlayerType, $locBlockId)) {
					return $locBlockId;
				}
			}
		}
		return false;
	}
	private function initBlockList($parPlayerType) {
		$locCenterZoneId = Zone::getZoneId(GeneratedConstante::$WORLD_CENTER_X, GeneratedConstante::$WORLD_CENTER_Y, 0);
		$this->serverBlockIdList = array();
		$this->secureBlockIdList = array();
		//Secure
		$req = "SELECT block.blockId,
				sqrt(
					 pow(x-".GeneratedConstante::$WORLD_CENTER_X.", 2)
					+pow(y-".GeneratedConstante::$WORLD_CENTER_Y.", 2))
					rangeToCenter 
				FROM block WHERE allianceId = 0 AND z "; 
		switch($parPlayerType) {
			case DungeonConstante::$PLAYER_TYPE_HUMAN_KNIGHT:
				//Only surface
				$req .= "=".Site::$ZONE_COORD_Z_GROUND_LEVEL;
				break;
			default:
				//Only underground
				$req .= "=".min(Site::$ZONE_COORD_Z_GROUND_LEVEL-2, Constante::getMinZ());
		}
		$req="$req ORDER BY z ASC, rangeToCenter ASC";
		$res = executer($req);
		while($row = mysql_fetch_array($res)) {
			$locBlockId = $row[0];
			list($x, $y, $z) = Block::getBlockCoord($locBlockId);
			if((Zone::staticMax2d($locCenterZoneId, $locBlockId)/Constante::$BLOCK_SIZE) < GeneratedConstante::$WORLD_TOP_HEIGHT) {
				$this->serverBlockIdList[floor($x/2)][floor($y/2)][floor($z/2)] = DungeonServer::$BLOCK_IS_SECURE;
				array_push($this->secureBlockIdList, $locBlockId);
			}
		}
		//echo "<br>";
		//Unsecure
		$res = executer("SELECT block.blockId FROM block WHERE allianceId > 0");
		while($row = mysql_fetch_array($res)) {
			$locBlockId = $row[0];
			list($x, $y, $z) = Block::getBlockCoord($locBlockId);
			for($locX = $x - 4*Constante::$BLOCK_SIZE; $locX <= $x + 4*Constante::$BLOCK_SIZE; $locX+=2*Constante::$BLOCK_SIZE) {
				for($locY = $y - 4*Constante::$BLOCK_SIZE; $locY <= $y + 4*Constante::$BLOCK_SIZE; $locY+=2*Constante::$BLOCK_SIZE) {
					for($locZ = $z - 2; $locZ <= $z + 2; $locZ+=2) {
						//Log::info("Unsecure [$locX][$locY][$locZ]");
						$this->serverBlockIdList[floor($locX/2)][floor($locY/2)][floor($locZ/2)] = DungeonServer::$BLOCK_IS_UNSECURE;
					}
				}
			}
		}

	}
	public function getAnHappyHomeBlockId($parPlayerType) {
		$locStart = microtime(true);
		$this->initBlockList($parPlayerType);

		$locLastHappyHomeId = $this->getLastHappyHomeId($parPlayerType);
		list($x, $y, $z) = Block::getBlockCoord($locLastHappyHomeId);
		if($this->isAnHappyHome($parPlayerType, $locLastHappyHomeId)) {
			Log::info("returns last happy home: $locLastHappyHomeId in ".((microtime(true)-$locStart)*1000)." ms for $parPlayerType");
			return $locLastHappyHomeId;
		}

		foreach($this->secureBlockIdList as $locBlockId) {
			if($this->isAnHappyHome($parPlayerType, $locBlockId)) {
				Log::info("get an happy home with $locBlockId in ".((microtime(true)-$locStart)*1000)." ms for $parPlayerType");
				$this->setLastHappyHome($parPlayerType, $locBlockId);
				return $locBlockId;
			}
		}
		Log::info("get no happy home in ".((microtime(true)-$locStart)*1000)." ms for $parPlayerType");
		return false;
	}
	private function isAnHappyHome($parPlayerType, $locBlockId) {
		//Log::info("test $locBlockId");
		if(false == $locBlockId) {
			return false;
		}
		list($x, $y, $z) = Block::getBlockCoord($locBlockId);
		if($this->serverBlockIdList[floor($x/2)][floor($y/2)][floor($z/2)] != DungeonServer::$BLOCK_IS_SECURE) {
			return false;
		}
		$locIsOk = true;
		//Log::info("[$x][$y][$z] is secure");
		if($parPlayerType == DungeonConstante::$PLAYER_TYPE_HUMAN_KNIGHT) {
			if($z != Site::$ZONE_COORD_Z_GROUND_LEVEL) {
				$locIsOk = false;
			}
		} else {
			if($z >= Site::$ZONE_COORD_Z_GROUND_LEVEL-1) {
				//echo $z;
				$locIsOk = false;
			}
		}
		if($locIsOk) {
			//Verify unit presence !
			global $gloObjectManager;
			$locBlock = $gloObjectManager->getBlock($locBlockId);
			//1 is for monster
			if($locBlock->isOtherAllianceObjectNear(1, 3, 3, 1)) {
				return false;
			}
			return $locBlockId;
		}
		return false;
	}
}
?>
Return current item: PhpBlock