mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-07-25 14:06:12 +00:00
Major refactor: Extract Database and Automation into domain-specific trait files
### Core Architecture Refactor - Split the `Database.php` class into domain-specific traits under `GameEngine/Database/`. - Split the `Automation` class into domain-specific traits under `GameEngine/Automation/`. - Grouped methods by functional domain for improved maintainability and navigation. - Preserved 100% backward compatibility. - No logic or behavioral changes. - Pure structural refactor.
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
<?php
|
||||
|
||||
#################################################################################
|
||||
## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ##
|
||||
## --------------------------------------------------------------------------- ##
|
||||
## Project: TravianZ ##
|
||||
## Filename: AutomationVillageUpkeep.php ##
|
||||
## Split&Refactor Shadow ##
|
||||
## Purpose: Population recalculation, resources, warehouses, loyalty, ##
|
||||
## oases ##
|
||||
## ##
|
||||
## Phase S2: Trait extracted from GameEngine/Automation.php ##
|
||||
## (Automation class). ##
|
||||
## Methods were moved IDENTICALLY, with no logic changes. ##
|
||||
## ##
|
||||
## License: TravianZ Project ##
|
||||
## Copyright: TravianZ (c) 2010-2026. All rights reserved. ##
|
||||
## URLs: https://travianz.org ##
|
||||
## https://github.com/Shadowss/TravianZ ##
|
||||
#################################################################################
|
||||
|
||||
trait AutomationVillageUpkeep {
|
||||
|
||||
|
||||
|
||||
public function procResType($ref, $mode = 0) {
|
||||
//Capital or only 1 village left = cannot be destroyed
|
||||
return addslashes(empty($build = Building::procResType($ref)) && !$mode ? RC_VILLAGE_CANT_BE : $build);
|
||||
}
|
||||
|
||||
function recountPop($vid, $use_cache = true){
|
||||
global $database;
|
||||
|
||||
$vid = (int) $vid;
|
||||
$fdata = $database->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user