<?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;
}
}
?>