<?php
include_once $PATH_TO_CODE."/script/zone.class.php";
include_once $PATH_TO_CODE."/script/realobject.class.php";
include_once $PATH_TO_CODE."/script/log.class.php";
include_once $PATH_TO_CODE."/script/tick/tick.class.php";
include_once $PATH_TO_CODE."/modules/dungeon/dungeonconstante.class.php";
include_once $PATH_TO_CODE."/modules/dungeon/objectmanager.class.php";
class MonsterChoiceAction {
private $zRangeFactor;
private $moveAlgo;
public function __construct($parMoveAlgo, $zRangeFactor=2.5) {
$this->moveAlgo = $parMoveAlgo;
$this->zRangeFactor = $zRangeFactor;
}
public function choiceAction(DungeonRealObject $locObject) {
global $gloObjectManager;
$locObject->setMoveAlgo($this->moveAlgo);
$locTargetZoneId = false;
$locBlock = $gloObjectManager->getBlock($locObject->blockId);
$locTargetZoneId = $this->getZoneTarget($locObject, $locBlock);
$locMoveIsSuccess=false;
$locMessage;
if($locTargetZoneId) {
$locMoveIsSuccess = $locObject->move($locTargetZoneId, $locMessage);
} else {
Log::info(" no target, then ", false);
$locTargetZoneId=$this->getRandTarget($locBlock, 3);
if($locTargetZoneId) {
$locMoveIsSuccess = $locObject->move($locTargetZoneId, $locMessage);
}
}
if(!$locMoveIsSuccess) {
$locTargetZoneId=$this->getRandTarget($locBlock, 3);
if($locTargetZoneId) {
$locMoveIsSuccess = $locObject->move($locTargetZoneId, $locMessage);
}
}
Log::info("action for ".$locObject->toStringPublicInfo()." move from $locObject->zoneId to $locTargetZoneId $locMessage");
}
public function getZoneTarget($parObject, $parBlock) {
$locTargetZone = array();
$locDetectRangeX = 2;
$locDetectRangeY = 2;
$locDetectRangeZ = 3;
//Ennemies land where we attack
$locRes = $parBlock->getOtherAllianceBlockNear($parObject->allianceId, $locDetectRangeX, $locDetectRangeY, $locDetectRangeZ, false);
while($row = mysql_fetch_array($locRes)) {
$locZoneId = $row[0];
list($x, $y, $z) = Zone::getZoneCoord($locZoneId);
$x += mt_rand(-2, 2);
$y += mt_rand(-2, 2);
$locZoneId = Zone::getZoneId($x, $y, $z);
$locRange = Zone::staticGetEuclideanDistance2dAndZ($parObject->zoneId, $locZoneId, $this->zRangeFactor);
$locRange = pow($locRange, 1.5)+3;
$locTargetZone[$locZoneId] = $locRange;
}
//Our land where we lost control
$locRes = $parBlock->getAllianceBlockNear($parObject->allianceId, $locDetectRangeX, $locDetectRangeY, $locDetectRangeZ, true);
while($row = mysql_fetch_array($locRes)) {
$locZoneId = $row[0];
list($x, $y, $z) = Zone::staticGetTextZoneCoord($locZoneId);
$x += mt_rand(-2, 2);
$y += mt_rand(-2, 2);
$locZoneId = Zone::getZoneId($x, $y, $z);
$locRange = Zone::staticGetEuclideanDistance2dAndZ($parObject->zoneId, $locZoneId, $this->zRangeFactor);
$locRange = pow($locRange, 1.5)+5;
$locTargetZone[$locZoneId] = $locRange;
}
$locRes = $parBlock->getOtherAllianceObjectNear($parObject->allianceId, $locDetectRangeX, $locDetectRangeY, $locDetectRangeZ);
while($row = mysql_fetch_array($locRes)) {
$locZoneId = $row[1];
$locRange = Zone::staticGetEuclideanDistance2dAndZ($parObject->zoneId, $locZoneId, $this->zRangeFactor);
if($locRange > 5) {
$locRange = pow($locRange, 1.3);
}
if($row[2]) {//Battle
$locRange += 5;
}
$locTargetZone[$locZoneId] = $locRange;
}
$locIgnoreRallyPointLevel = 0;
$locRes = $this->getRallyPointObjectNear($parObject->allianceId, $parBlock->blockId, $locDetectRangeX+1, $locDetectRangeY+1, $locDetectRangeZ);
while($row = mysql_fetch_array($locRes)) {
$locZoneId = $row[0];
$locCurrentRallyPointLevel = $row[1];
if($locCurrentRallyPointLevel > $locIgnoreRallyPointLevel) {
$locRange = Zone::staticGetEuclideanDistance2dAndZ($parObject->zoneId, $locZoneId, 1);
if($locRange > 6) {//Ignore too near rally point
$locTargetZone[$locZoneId] = $locRange;
}
$locIgnoreRallyPointLevel = max($locIgnoreRallyPointLevel, $locCurrentRallyPointLevel);
}
}
asort($locTargetZone);
$locKeys = array_keys($locTargetZone);
//print_r($locTargetZone);
//print_r($locKeys);
return array_shift($locKeys);
}
public function getRandTarget($locBlockOri, $parRange=2) {
$locTargetZoneId=false;
list($x, $y, $z) = Zone::getZoneCoord($locBlockOri->blockId);
$x += mt_rand(-$parRange*Constante::$BLOCK_SIZE, $parRange*Constante::$BLOCK_SIZE);
$y += mt_rand(-$parRange*Constante::$BLOCK_SIZE, $parRange*Constante::$BLOCK_SIZE);
if($z < round((Constante::getMinZ()+Constante::getMaxZ())/2)) {
//Up
$z += mt_rand(-$parRange, $parRange+1);
} else {
//Down
$z += mt_rand(-($parRange+1), $parRange);
}
$z = max(Constante::getMinZ(), $z);
$z = min(Constante::getMaxZ(), $z);
$x = max(Constante::getMinX(), $x);
$x = min(Constante::getMaxX(), $x);
$y = max(Constante::getMinY(), $y);
$y = min(Constante::getMaxY(), $y);
$locNewZoneId = Zone::getZoneId($x, $y, $z);
if(Zone::staticCanExist($locNewZoneId)) {
Log::info("rand ", false);
return $locNewZoneId;
} else {
Log::info("$locNewZoneId doesn't exist ", false);
return false;
}
}
/**
* @return mysql_res with zoneId and level value, desc level value
*/
private function getRallyPointObjectNear($parAllianceId, $parBlockId, $parBlockRangeX=0, $parBlockRangeY=0, $parBlockRangeZ=0) {
$locTargetBlockList = Block::getStaticBlockIdsFromXYZ($parBlockId, $parBlockRangeX, $parBlockRangeY, $parBlockRangeZ);
/*
$locTargetBlockListToRemove1 = Block::getStaticBlockIdsFromXYZ($parBlockId, 1, 1, 0);
$locTargetBlockList = array_diff($locTargetBlockList, $locTargetBlockListToRemove1);
$locTargetBlockListToRemove2 = Block::getStaticBlockIdsFromXYZ($parBlockId, 0, 0, 1);
$locTargetBlockList = array_diff($locTargetBlockList, $locTargetBlockListToRemove2);
*/
return executer("SELECT object.zoneId, objectInfo.value
FROM object, objectInfo
WHERE object.allianceId=$parAllianceId
AND objectType=".DungeonConstante::$REAL_OBJECT_TYPE_RALLY_POINT."
AND objectInfo.type1=".DungeonRealObject::$REAL_OBJECT_INFO_TYPE1_LEVEL."
AND objectInfo.type2=".DungeonRealObject::$REAL_OBJECT_INFO_TYPE2_CURRENT_POINT."
AND objectInfo.objectId=object.objectId
AND object.blockId IN ".getWhereClauseList($locTargetBlockList)
." ORDER BY objectInfo.value DESC");
}
}
?>