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