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