Location: PHPKode > projects > PhpBlock > A9.8/modules/dungeon/tick/monstercreate.class.php
<?php
include_once $PATH_TO_CODE."/script/tick/allincludefortick.php";

class MonsterCreateTick extends Tick {
	public function getName() {
		return "Monster create";
	}
	public static function createMonsterPlayer() {
		executer("REPLACE INTO `player` (playerId, allianceId, isLock, `playerName`, `firmName`, `login` , `pass` , `cash`, `color`, unlockStr, email)
       		VALUES (1, 1, 0, 'monster', 'monster', 'monster', MD5('".urand().urand()."'), 0, '000000', '', '".Site::$SITE_ADMIN."')");
		executer("REPLACE INTO `alliance` (allianceId, name, leaderId) VALUES (1, 'monster', 1)");
	}
	public function run() {
		global $gloObjectManager;

		MonsterCreateTick::createMonsterPlayer();
		$res = executer("SELECT blockId from object
		where objectType=".DungeonConstante::$REAL_OBJECT_TYPE_MONSTER_NEST."
		AND isLobotomize=".RealObject::$UNIT_IS_NOT_LOBOTOMIZE);
		while($row = mysql_fetch_array($res)) {
			Log::info(" monster nest");
			$locBlock = $gloObjectManager->getBlock($row[0]);
			$this->generateMonster($locBlock, false, 5, 15, true);
		}

		$res = executer("SELECT blockId
                         FROM block
                         WHERE (1.0/2000.0) > RAND()");
		while($row = mysql_fetch_array($res)) {
			Log::info(" random block ");
			$locBlock = $gloObjectManager->getBlock($row[0]);
			$this->generateMonster($locBlock, true, 3, 5);
		}
	}

	/**
	 *
	 */
	public function generateMonster($parBlock, $parRandAround, $parCountNewMonster=1, $parMaxMonsterNear, $parIgnoreBlockOwner=false) {
		list($x, $y, $z) = Block::getBlockCoord($parBlock->blockId);

		global $gloObjectManager;
		$locNewBlock = false;
		$locMaxTry = 20;
		$locCurrentTry = 0;
		$locRange = 1;
		do {
			if($locCurrentTry > 0) {
				$locRange = 1;
			}
			if($parRandAround) {
				$x += Constante::$BLOCK_SIZE*mt_rand(-$locRange, $locRange);
				$y += Constante::$BLOCK_SIZE*mt_rand(-$locRange, $locRange);
				if($z == Constante::getMinZ()) {
					$z = mt_rand(Constante::getMinZ(), Constante::getMaxZ());
				}
				$z += mt_rand(-2, 1);
				$z += mt_rand(-1, 1);

				$z = max(Constante::getMinZ(), $z);
				$z = min(Constante::getMaxZ(), $z);
				$x = max(Constante::getMinBlockX(), $x);
				$x = min(Constante::getMaxBlockX(), $x);
				$y = max(Constante::getMinBlockY(), $y);
				$y = min(Constante::getMaxBlockY(), $y);
			}

			$locContinueLoop = true;
			$locNewBlockId = Block::getBlockIdWithCenterCoord($x, $y, $z);
			if(!Block::exist($locNewBlockId)) {
				Log::error(" block ".$locNewBlockId." didn't exist");
				$locNewBlock = false;
				break;
			}
			$locNewBlock = $gloObjectManager->getBlock($locNewBlockId);
			if($this->isValidBlock($locNewBlock, $parMaxMonsterNear, $parIgnoreBlockOwner)) {
				Log::info(" valid block: ".$locNewBlockId." create $parCountNewMonster monsters");
				break;
			} else {
				Log::info(" invalid block: ".$locNewBlockId);
			}
			Log::info("next try");
		} while($locCurrentTry++ < $locMaxTry);

		if($this->isValidBlock($locNewBlock, $parMaxMonsterNear, $parIgnoreBlockOwner)) {
			for($i = 0; $i < $parCountNewMonster; $i++) {
				list($x, $y, $z) = Zone::getZoneCoord($locNewBlock->blockId);
				$x += mt_rand(-Constante::$HALF_BLOCK_SIZE, Constante::$HALF_BLOCK_SIZE);
				$y += mt_rand(-Constante::$HALF_BLOCK_SIZE, Constante::$HALF_BLOCK_SIZE);
				if(Zone::staticCanExistXYZ($x, $y, $z)) {
					$locNewZoneId = Zone::getZoneId($x, $y, $z);
					$locNewZone = $gloObjectManager->getZone($locNewZoneId);
					$this->createMonster($locNewZone);
				}
			}
		} else {
			Log::info(" no create monster cause invalid block");
		}
	}
	public function isValidBlock($parBlock, $parMaxMonsterNear=5, $parIgnoreBlockOwner=false) {
		if(!$parBlock) {
			Log::info("no block as parameter");
			return false;
		}
		list($x, $y, $z) = Block::getBlockCoord($parBlock->zoneId);
		if($locResult||mysql_fetch_array($parBlock->getOtherAllianceObjectNear(1, 1, 1, 1))) {
			Log::info("others units are here");
			return false;
		}
		global $gloObjectManager;
		if(!$parIgnoreBlockOwner) {
			//No newbies
			$locMaxRange = 4;
			for($i = 1; $i <= $locMaxRange; $i++) {
				$locResultPlayerId = $parBlock->getPlayersIdAround($i, $i, ceil($i*0.75));
				foreach($locResultPlayerId as $locPlayerId) {
					$locPlayerLevel = $gloObjectManager->getPlayer($locPlayerId)->getLevel();
					if(1 == $i) {
						Log::info("player $locPlayerId is too near (level $locPlayerLevel)");
						return false;
					}
					$locMaxPlayerLevel = DungeonConstante::$PLAYER_LEVEL_NEWBIE+($locMaxRange-$i)*5;
					if($locPlayerLevel < $locMaxPlayerLevel) {
						Log::info("player $locPlayerId is too weak (level $locPlayerLevel for a max of $locMaxPlayerLevel)");
						return false;
					}
				}
			}
		}
		//less than 5 monsters in 2,2,2
		$locCountOfMonsterNest = $parBlock->getAllianceObjectNearCount(1, 3, 3, 3, DungeonConstante::$REAL_OBJECT_TYPE_MONSTER_NEST);
		$locCountOfMonster = $parBlock->getAllianceObjectNearCount(1, 3, 3, 3) - $locCountOfMonsterNest;
		Log::info("here $locCountOfMonster monsters (monster nest: $locCountOfMonsterNest)");
		if($locCountOfMonster >= $parMaxMonsterNear) {
			Log::info("already too much monster here");
			return false;
		}
		return true;
	}
	public function createMonster($parZone) {
		global $gloObjectManager;
		Log::info(" create monster at $parZone->zoneId");
		if(rand(1, 100) <= 20) {
			$locMonsterId = Spectre::create($parZone, 1, false);
		} else {
			$locMonsterId = Skeleton::create($parZone, 1, false);
		}
		Log::info("Create the monster with the average player level near");
		$parBlock = $gloObjectManager->getBlock($parZone->blockId);
		$locResultPlayerId = $parBlock->getPlayersIdAround(4, 4, 4);
		$locCountBlockPlayerAround = 0;
		$locIncreaseXP = 0;
		foreach($locResultPlayerId as $locPlayerId) {
			$locPlayerLevel = $gloObjectManager->getPlayer($locPlayerId)->getLevel();
			$locIncreaseXpForThisPlayer = pow(normalizePlayerLevel($locPlayerLevel), 1.1)+5;
			$locIncreaseXP += $locIncreaseXpForThisPlayer;
			$locCountBlockPlayerAround++;
		}
		$locMonster = $gloObjectManager->getRealObject($locMonsterId);
		//randomize XP +-50%
		$locIncreaseXP = rand($locIncreaseXP*0.5, $locIncreaseXP*1.5);
		if($locCountBlockPlayerAround > 0) {
			//"Average"
			$locIncreaseXP = $locIncreaseXP/$locCountBlockPlayerAround;
			Log::info("increase XP: $locIncreaseXP");
			$locMonster->addXP($locIncreaseXP);
			Log::info("new level is: ".$locMonster->getLevel());
		}
		$locMonster->setActionPoint(0);
		$locMonster->setIAMode(RealObject::$IA_MODE_MEDIUM_AGRESSIVE);
		foreach($locResultPlayerId as $locPlayerId) {
			PlayerMessage::getInstance()->addPlayerInfo($locPlayerId,
			"a monster level ".$locMonster->getLevel()." has been created",
			PlayerMessage::$VERY_BAD, $parZone->zoneId);
		}
	}
}
function normalizePlayerLevel($parLevel) {
	return $parLevel/DungeonConstante::$PLAYER_LEVEL_NEWBIE;
}
?>
Return current item: PhpBlock