getResourceLevel($vid, $use_cache); $popTot = 0; for ($i = 1; $i <= 40; $i++) { $lvl = $fdata["f".$i]; $building = $fdata["f".$i."t"]; if($building) $popTot += $this->buildingPOP($building, $lvl); } Building::recountCP($database, $vid); $q = "UPDATE ".TB_PREFIX."vdata set pop = $popTot where wref = $vid"; mysqli_query($database->dblink, $q); $owner = $database->getVillageField($vid, "owner"); // Milestone: first player ever to reach 1000 total population, // summed across all their villages. recountPop() is the single // funnel every population-changing event (building, demolishing, // founding/conquering a village) already passes through, so this // is the one place that's guaranteed to catch the threshold being // crossed regardless of which village/action caused it. // Excludes owner 3 (Natars) — see Artifacts::NATARS_UID — same // convention already used elsewhere in this file (e.g. the // "fix natar report by ronix" check a few hundred lines below). if (defined('NEW_FUNCTIONS_MILESTONES') && NEW_FUNCTIONS_MILESTONES && $owner > 0 && $owner != 3) { $totalPop = (int) $database->getVSumField($owner, 'pop', false); if ($totalPop >= 1000) { $database->recordMilestoneIfFirst('population_1000', $owner, $vid); } } $this->procClimbers($owner); return $popTot; } function buildingPOP($f, $lvl){ $name = "bid".$f; global $$name; $popT = 0; $dataarray = $$name; for ($i = 0; $i <= $lvl; $i++) { $popT += ((isset($dataarray[$i]) && isset($dataarray[$i]['pop'])) ? $dataarray[$i]['pop'] : 0); } return $popT; } private function loyaltyRegeneration() { global $database; $array = []; $array = $database->getProfileVillages(0, 6); if(!empty($array)) { foreach($array as $loyalty) { if (($t25_level = $this->getTypeLevel(25, $loyalty['wref'])) >= 1) { $value = $t25_level; }elseif(($t26_level = $this->getTypeLevel(26, $loyalty['wref'])) >= 1){ $value = $t26_level; } else $value = 0; if($value > 0){ $newloyalty = min(100, $loyalty['loyalty'] + $value * (time() - $loyalty['lastupdate2']) / 3600); $q = "UPDATE ".TB_PREFIX."vdata SET loyalty = $newloyalty, lastupdate2=".time()." WHERE wref = '".$loyalty['wref']."'"; $database->query($q); } } } $array = []; $q = "SELECT conqured, loyalty, lastupdated, wref FROM ".TB_PREFIX."odata WHERE loyalty < 100"; $array = $database->query_return($q); if(!empty($array)) { foreach($array as $loyalty) { $value = $this->getTypeLevel(37, $loyalty['conqured']); if($value > 0){ $newloyalty = min(100, $loyalty['loyalty'] + $value * (time() - $loyalty['lastupdated']) / 3600); $q = "UPDATE ".TB_PREFIX."odata SET loyalty = $newloyalty, lastupdated=".time()." WHERE wref = '".$loyalty['wref']."'"; $database->query($q); } } } } public function getTypeLevel($tid, $vid) { global $database; $keyholder = []; $resourcearray = $database->getResourceLevel($vid); foreach(array_keys($resourcearray, $tid) as $key) { if(strpos($key,'t')) { $key = preg_replace("/[^0-9]/", '', $key); array_push($keyholder, $key); } } $element = count($keyholder); if($element >= 2) { if($tid <= 4) { $temparray = []; for($i = 0; $i <= $element - 1; $i++) { array_push($temparray,$resourcearray['f'.$keyholder[$i]]); } foreach ($temparray as $key => $val) { if ($val == max($temparray)) $target = $key; } } else { $target = 0; for($i = 1; $i <= $element - 1; $i++) { if($resourcearray['f'.$keyholder[$i]] > $resourcearray['f'.$keyholder[$target]]) { $target = $i; } } } } else if($element == 1) $target = 0; else return 0; if(!empty($keyholder[$target])) return $resourcearray['f'.$keyholder[$target]]; else return 0; } // Clamp resources/storage up to their minimums for the given table (vdata or // odata): negative resources back to 0 and maxstore/maxcrop back to // STORAGE_BASE. This floor pass is identical for both tables, so both // pruneResource() (vdata) and pruneOResource() (odata) share it. The $table // argument is an internal constant string, never user input. private function pruneResourceMinimums($table) { global $database; $database->query("UPDATE ".TB_PREFIX.$table." SET wood = IF(wood < 0, 0, wood), clay = IF(clay < 0, 0, clay), iron = IF(iron < 0, 0, iron), crop = IF(crop < 0, 0, crop), maxstore = IF(maxstore < ".STORAGE_BASE.", ".STORAGE_BASE.", maxstore), maxcrop = IF(maxcrop < ".STORAGE_BASE.", ".STORAGE_BASE.", maxcrop) WHERE maxstore < ".STORAGE_BASE." OR maxcrop < ".STORAGE_BASE." OR wood < 0 OR clay < 0 OR iron < 0 OR crop < 0"); } private function pruneOResource() { if(!ALLOW_BURST) { $this->pruneResourceMinimums('odata'); } } private function pruneResource() { global $database; if(!ALLOW_BURST) { $this->pruneResourceMinimums('vdata'); $database->query("UPDATE ".TB_PREFIX."vdata SET wood = IF(wood > maxstore, maxstore, wood), clay = IF(clay > maxstore, maxstore, clay), iron = IF(iron > maxstore, maxstore, iron), crop = IF(crop > maxcrop, maxcrop, crop) WHERE wood > maxstore OR clay > maxstore OR iron > maxstore OR crop > maxcrop"); } } private function culturePoints() { global $database; $database->updateVSumField('cp'); } /** * Recompute a warehouse/granary capacity after a build completion. * Returns [$fieldDbName, $max]: the vdata column to update and its new value. */ private function updateStorageCapacity($type, $level, $villageData) { global $bid10, $bid11, $bid38, $bid39; $fieldDbName = (in_array($type, [10, 38]) ? 'maxstore' : 'maxcrop'); $max = $villageData[$fieldDbName]; if($level == 1 && $max == STORAGE_BASE) $max = STORAGE_BASE; if ($level != 1) $max -= ${'bid'.$type}[$level - 1]['attri'] * STORAGE_MULTIPLIER; $max += ${'bid'.$type}[$level]['attri'] * STORAGE_MULTIPLIER; return [$fieldDbName, $max]; } private function getPop($tid, $level) { $name = "bid".$tid; global $$name; $dataarray = $$name; $pop = $dataarray[($level + 1)]['pop']; $cp = $dataarray[($level + 1)]['cp']; return [$pop, $cp]; } private function updateORes($bountywid) { global $database; $oasisInfoArray = $database->getOasisV($bountywid); $timepast = time() - $oasisInfoArray['lastupdated']; $nwood = (OASIS_WOOD_PRODUCTION / 3600) * $timepast; $nclay = (OASIS_CLAY_PRODUCTION / 3600) * $timepast; $niron = (OASIS_IRON_PRODUCTION / 3600) * $timepast; $ncrop = (OASIS_CROP_PRODUCTION / 3600) * $timepast; $database->modifyOasisResource($bountywid, $nwood, $nclay, $niron, $ncrop, 1); $database->updateOasis($bountywid); } private function updateRes($bountywid) { global $database, $technology; //Get village infos $villageInfoArray = $database->getVillage($bountywid); //Get building and resource fields array $resArray = $database->getResourceLevel($bountywid, false); //Get oasis array $oasisArray = $database->getOasis($bountywid); //Get an array with the numbers of the oasis $numberOfOasis = $this->bountysortOasis($oasisArray); //Set the village population (if WW Villages, it's halved) $villagePopulation = !$villageInfoArray['natar'] ? $villageInfoArray['pop'] : round($villageInfoArray['pop'] / 2); //Get the upkeep of the village $upkeep = $technology->getUpkeep($this->getAllUnits($bountywid), 0, $bountywid); //Calculate the produced resources $timepast = time() - $villageInfoArray['lastupdate']; $nwood = ($this->bountyGetResourceProd($resArray, $numberOfOasis, 1) / 3600) * $timepast; $nclay = ($this->bountyGetResourceProd($resArray, $numberOfOasis, 2) / 3600) * $timepast; $niron = ($this->bountyGetResourceProd($resArray, $numberOfOasis, 3) / 3600) * $timepast; $ncrop = (($this->bountyGetResourceProd($resArray, $numberOfOasis, 4) - $villagePopulation - $upkeep) / 3600) * $timepast; $database->modifyResource($bountywid, $nwood, $nclay, $niron, $ncrop, 1); $database->updateVillage($bountywid); } private function getsort_typeLevel($tid, $resarray) { $keyholder = []; foreach(array_keys($resarray, $tid) as $key) { if(strpos($key, 't')) { $key = preg_replace("/[^0-9]/", '', $key); array_push($keyholder, $key); } } $element = count($keyholder); if($element >= 2) { if($tid <= 4) { $temparray = []; for($i = 0; $i <= $element - 1; $i++) { array_push($temparray, $resarray['f'.$keyholder[$i]]); } foreach ($temparray as $key => $val) { if ($val == max($temparray)) $target = $key; } } } else if($element == 1) $target = 0; else return 0; if(!empty($keyholder[$target])) return $resarray['f'.$keyholder[$target]]; else return 0; } private function updateStore() { global $database, $bid10, $bid38, $bid11, $bid39; $result = mysqli_query($database->dblink, 'SELECT * FROM `' . TB_PREFIX . 'fdata`'); mysqli_begin_transaction($database->dblink); while ($row = mysqli_fetch_assoc($result)) { $ress = $crop = 0; for ($i = 19; $i < 40; ++$i) { //Warehouse if ($row['f' . $i . 't'] == 10) { $ress += ((isset($bid10[$row['f' . $i]]) && isset($bid10[$row['f' . $i]]['attri'])) ? $bid10[$row['f' . $i]]['attri'] * STORAGE_MULTIPLIER : 0); } //Great warehouse if ($row['f' . $i . 't'] == 38) { $ress += ((isset($bid38[$row['f' . $i]]) && isset($bid38[$row['f' . $i]]['attri'])) ? $bid38[$row['f' . $i]]['attri'] * STORAGE_MULTIPLIER : 0); } //Granary if ($row['f' . $i . 't'] == 11) { $crop += ((isset($bid11[$row['f' . $i]]) && isset($bid11[$row['f' . $i]]['attri'])) ? $bid11[$row['f' . $i]]['attri'] * STORAGE_MULTIPLIER : 0); } //Great granary if ($row['f' . $i . 't'] == 39) { $crop += ((isset($bid39[$row['f' . $i]]) && isset($bid39[$row['f' . $i]]['attri'])) ? $bid39[$row['f' . $i]]['attri'] * STORAGE_MULTIPLIER : 0); } } // no need for update, since we didn't find any warehouses or granaries // and maximums would have been set to correct values inside prune* functions already if ($ress == 0 && $crop == 0) continue; // maxstore nor maxcrop can go below the minimum threshold if ($ress < STORAGE_BASE) $ress = STORAGE_BASE; if ($crop < STORAGE_BASE) $crop = STORAGE_BASE; mysqli_query($database->dblink,'UPDATE `' . TB_PREFIX . 'vdata` SET `maxstore` = ' . (int) $ress . ', `maxcrop` = ' . (int) $crop . ' WHERE `wref` = ' . (int) $row['vref']); } mysqli_commit($database->dblink); } private function regenerateOasisTroops() { global $database; $timeFinal = time() - NATURE_REGTIME; $q = "SELECT wref FROM " . TB_PREFIX . "odata where conqured = 0 and lastupdated2 < $timeFinal"; $array = $database->query_return($q); if (count($array)) { $ids = []; foreach($array as $oasis) $ids[] = $oasis['wref']; $database->regenerateOasisUnits($ids, true); } } }