Location: PHPKode > projects > PhpBlock > A9.8/modules/dungeon/algorithm/monsterchoiceaction.class.php
<?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");
	}
}
?>
Return current item: PhpBlock