<?php
include_once $PATH_TO_CODE."/script/tick/allincludefortick.php";
class PopulationTick extends TickRunnable {
private $monsterChoiceAction;
public function __construct() {
global $gloObjectManager;
$locMoveAlgo = $gloObjectManager->getPathFinder(200, 20, 4.0);
$locMoveAlgo->globalReturnLastChoiceOnFailure = true;
$this->monsterChoiceAction = new MonsterChoiceAction($locMoveAlgo);
}
public function getName() {
return "Population";
}
public function run() {
global $gloObjectManager;
$locBeginInMs=microtime(true)*1000;
$res = executer("SELECT block.playerId, SUM(zone.population)+".(DungeonConstante::$MAX_POPULATION_PER_ZONE*10)."
FROM block JOIN zone USING(blockId)
WHERE block.playerId > 1
GROUP BY block.playerId");
$locDurationPopulationInMs = microtime(true)*1000-$locBeginInMs;
Log::info("Player population init: ".$locDurationPopulationInMs."ms");
while($row = mysql_fetch_array($res)) {
$locBeginWhileInMs=microtime(true)*1000;
$this->growPlayer($row[0], $row[1]);
Log::info("Player population duration: ".(microtime(true)*1000-$locBeginWhileInMs)."ms");
}
}
public function growPlayer($parPlayerId, $parPopulation) {
global $gloObjectManager;
$locOldLoadBlockInsteadOneZone = $gloObjectManager->loadBlockInsteadOneZone;
$gloObjectManager->loadBlockInsteadOneZone = false;
$locActionCount = ceil(sqrt($parPopulation)/(50));
Log::info("gow player ($parPlayerId) with current population at $parPopulation, action count is $locActionCount");
$locPlayer = $gloObjectManager->getPlayer($parPlayerId);
$locForceMonsterCreation = ($locPlayer->IAMode > 0);
if($locForceMonsterCreation) {
$locPercentWarrior = 0.1;
} else {
$locPercentWarrior = 0.001;
}
switch($locPlayer->playerType) {
case DungeonConstante::$PLAYER_TYPE_UNDEAD:
//Undead population growth is slow
$locPopulationToAddInit = 1500;
$locPercentToGrowOutside = 0.025;
$locPrefZ = -1;
$locPercentWarrior*=0.75;
break;
case DungeonConstante::$PLAYER_TYPE_HUMAN_KNIGHT:
$locPopulationToAddInit = 2000;
$locPercentToGrowOutside = 0.05;
$locPrefZ = +1;
break;
default://Orkish
$locPopulationToAddInit = 2200;
$locPercentToGrowOutside = 0.055;
$locPrefZ = -1;
$locPercentWarrior*=1.05;
break;
}
$locUnitToCreate = 0;
$locGrowOutside = 0;
for($i=0; $i < $locActionCount; $i++) {
if(urand() < $locPercentWarrior) {
$locUnitToCreate++;
}
if(urand() <= $locPercentToGrowOutside) {
$locGrowOutside++;
}
}
$locActionCount -= $locUnitToCreate;
$locActionCount -= $locGrowOutside;
Log::info("increase population in already populated area");
$locBeginInMs=microtime(true)*1000;
while($locActionCount > 0) {//Standard grow
$resZoneForAction = executer("SELECT zone.zoneId
FROM block JOIN zone ON block.blockId=zone.blockId
WHERE block.playerId=$parPlayerId
AND population > 0
AND population < ".DungeonConstante::$MAX_POPULATION_PER_ZONE."
ORDER BY RAND() LIMIT $locActionCount");
while($locActionCount-- > 0 && $row = mysql_fetch_array($resZoneForAction)) {
$locZone = $gloObjectManager->getZone($row[0]);
$locPopulationToAdd = round($locPopulationToAddInit*urand()*2);
$locZoneHasBeenFound = false;
//Increase here
$locPopulationForTargetZone = $locZone->getPopulation();
$locPopulationForTargetZone = max(100, $locPopulationForTargetZone+$locPopulationToAdd);
Log::info("increase population to $locPopulationForTargetZone from ".$locZone->getPopulation()." on $locZone->zoneId for $locPlayer->playerName");
$locZone->setPopulation($locPopulationForTargetZone);
}
}
Log::info("Increase population standard duration: ".(microtime(true)*1000-$locBeginInMs)."ms");
Log::info("Increase population outside");
$locBeginInMs=microtime(true)*1000;
while($locGrowOutside > 0) {
$resZoneForAction = executer("SELECT zone.zoneId
FROM block JOIN zone ON block.blockId=zone.blockId
WHERE block.playerId=$parPlayerId
ORDER BY RAND() LIMIT $locGrowOutside");
while($locGrowOutside-- > 0 && $row = mysql_fetch_array($resZoneForAction)) {
$locZone = $gloObjectManager->getZone($row[0]);
$locPopulationToAdd = round($locPopulationToAddInit*urand()*2);
$locZoneHasBeenFound = false;
$locTry=0;
//Increase here
$locTargetZone = $locZone;
do {
Log::info("Increase somewhere else ".$locTargetZone->zoneId);
if(0==$locTry) {
$locDiffX = rand(-6, 6);
$locDiffY = rand(-6, 6);
if(rand(1, 100) == 1) {
Log::info("change z !");
if($locPrefZ < 0) {
$locDiffZ = max(-1, rand(-3, 1));
} else {
$locDiffZ = min(1, rand(-1, 3));
}
}
} else {
$locDiffX = rand(-2, 2);
$locDiffY = rand(-2, 2);
}
$locNewZ = $locTargetZone->z+$locDiffZ;
$locNewZ = Constante::minMaxZ($locNewZ);
$locTargetZone = $gloObjectManager->getZone(
Zone::getZoneId(
$locTargetZone->x+$locDiffX,
$locTargetZone->y+$locDiffY,
$locNewZ));
if(!$locTargetZone) {
$locTargetZone = $locZone;
}
$locTargetBlock = $gloObjectManager->getBlock($locTargetZone->blockId);
if($this->isPopulable($locTargetZone)) {
if($locTargetBlock->allianceId == 0 || $locTargetBlock->allianceId == $locPlayer->allianceId) {
if($locPlayer->playerType == DungeonConstante::$PLAYER_TYPE_UNDEAD) {
$locTargetZone->setZoneType(DungeonConstante::$ZONE_TYPE_NECROPOLIS);
} else {
$locTargetZone->setZoneType(DungeonConstante::$ZONE_TYPE_CITY);
}
$locPopulationForTargetZone = $locTargetZone->getPopulation();
$locPopulationForTargetZone = max(100, $locPopulationForTargetZone+$locPopulationToAdd);
if($locTargetBlock->allianceId == 0) {
Log::info("conquer target block $locTargetBlock->blockId");
$locTargetBlock->setPlayerId($locPlayer->playerId);
}
Log::info("increase population outside to ".$locPopulationForTargetZone." on $locTargetZone->zoneId for $locPlayer->playerName");
$locTargetZone->setPopulation($locPopulationForTargetZone);
$locZoneHasBeenFound = true;
}
}
} while(++$locTry < 10 && !$locZoneHasBeenFound);
}
Log::info("Player grow outside duration: ".(microtime(true)*1000-$locBeginInMs)."ms");
$gloObjectManager->loadBlockInsteadOneZone = true;
Log::info("create warrior");
$locBeginInMs=microtime(true)*1000;
while($locUnitToCreate > 0) {
$resZoneForAction = executer("SELECT zone.zoneId
FROM block JOIN zone ON block.blockId=zone.blockId
WHERE block.playerId=$parPlayerId
AND population > 0
AND occupedWithMovable = 0
AND occuped = 0
ORDER BY population DESC LIMIT $locUnitToCreate");
while($locUnitToCreate-- > 0 && $row = mysql_fetch_array($resZoneForAction)) {
$locZone = $gloObjectManager->getZone($row[0]);
if(!$locZone->isOccuped()) {
$locBlock = $gloObjectManager->getBlock($locZone->blockId);
$locObject = createRandomUnit($locZone, $locPlayer, DungeonConstante::calculateXpUnitAboutPopulation($locBlock->getAveragePopulation()));
$this->monsterChoiceAction->choiceAction($locObject);
$locZone->setPopulation($locZone->getPopulation() - DungeonConstante::$POPULATION_LOSS_FOR_UNIT_CREATION);
}
}
}
Log::info("Player create unit duration: ".(microtime(true)*1000-$locBeginInMs)."ms");
}
$gloObjectManager->loadBlockInsteadOneZone = $locOldLoadBlockInsteadOneZone;
}
private function isPopulable($parZone) {
if($parZone) {
return $parZone->population < DungeonConstante::$MAX_POPULATION_PER_ZONE
&& (DungeonConstante::$ZONE_TYPE_ROCK == $parZone->zoneType
|| Constante::$ZONE_TYPE_PLAIN == $parZone->zoneType
|| DungeonConstante::$ZONE_TYPE_CITY == $parZone->zoneType
|| DungeonConstante::$ZONE_TYPE_NECROPOLIS == $parZone->zoneType);
}
return false;
}
}
?>