Starvation refactor

Refactor part 2 of the "Starvation" function:
+Trapped troops in other villages will die of starvation
+Returning troops will die of starvaton

Database.php:
+Added "modifyPrisoners" function
This commit is contained in:
iopietro
2018-04-11 00:16:39 +02:00
parent 01e1df7493
commit 8b3a387cd5
2 changed files with 134 additions and 166 deletions
+105 -159
View File
@@ -4882,18 +4882,25 @@ class Automation {
unlink($autoprefix."GameEngine/Prevention/starvation.txt"); unlink($autoprefix."GameEngine/Prevention/starvation.txt");
} }
//starvation is disabled during Easter/Holidays/Christmas
if(PEACE) return;
$ourFileHandle = fopen($autoprefix."GameEngine/Prevention/starvation.txt", 'w'); $ourFileHandle = fopen($autoprefix."GameEngine/Prevention/starvation.txt", 'w');
fclose($ourFileHandle); fclose($ourFileHandle);
$time = time(); $time = time();
//TODO: Starvation should be updated in every village!
//update starvation //update starvation
$getvillage = $database->getVillage($village->wid); $getvillage = $database->getVillage($village->wid);
$starv = $getvillage['starv']; $starv = $getvillage['starv'];
if ($getvillage['owner']!=3 && $starv==0) { if ($getvillage['owner'] != 3 && $starv == 0)
{
$crop = $database->getCropProdstarv($village->wid); $crop = $database->getCropProdstarv($village->wid);
$unitarrays = $this->getAllUnits($village->wid); $unitarrays = $this->getAllUnits($village->wid);
$village_upkeep = $getvillage['pop'] + $this->getUpkeep($unitarrays, 0); $village_upkeep = $getvillage['pop'] + $this->getUpkeep($unitarrays, 0);
if ($crop < $village_upkeep){ if ($crop < $village_upkeep)
{
// add starv data // add starv data
$database->setVillageField($village->wid, 'starv', $village_upkeep); $database->setVillageField($village->wid, 'starv', $village_upkeep);
if($starv==0) $database->setVillageField($village->wid, 'starvupdate', time()); if($starv==0) $database->setVillageField($village->wid, 'starvupdate', time());
@@ -4907,151 +4914,81 @@ class Automation {
$starvarray = $database->getStarvation(); $starvarray = $database->getStarvation();
$vilIDs = []; $vilIDs = [];
foreach ($starvarray as $starv){ foreach ($starvarray as $starv) $vilIDs[] = $starv['wref'];
$vilIDs[$starv['wref']] = true;
} // cache
$vilIDs = array_keys($vilIDs);
$database->getEnforceVillage($vilIDs, 0); $database->getEnforceVillage($vilIDs, 0);
$database->getOasisEnforce($vilIDs, 2); $database->getOasisEnforce($vilIDs, 2);
$database->getOasisEnforce($vilIDs, 3); $database->getOasisEnforce($vilIDs, 3);
$database->getPrisoners($vilIDs, 1);
$database->getMovement(3, $vilIDs, 0); $database->getMovement(3, $vilIDs, 0);
$database->getMovement(4, $vilIDs, 1);
foreach ($starvarray as $starv){ foreach ($starvarray as $starv)
{
$unitarrays = $this->getAllUnits($starv['wref']); $unitarrays = $this->getAllUnits($starv['wref']);
$upkeep = $starv['pop'] + $this->getUpkeep($unitarrays, 0, $starv['wref']); $upkeep = $starv['pop'] + $this->getUpkeep($unitarrays, 0, $starv['wref']);
//TODO: getting enforcements could be done by using a recursive function
// get enforce other player from oasis
$enforceoasis = $database->getOasisEnforce($starv['wref'], 2);
$maxcount = $totalunits = 0; $maxcount = $totalunits = 0;
if(count($enforceoasis)>0){
foreach ($enforceoasis as $enforce){ $enforceArrays = $prisonerArrays = $unitArrays = $attackArrays = $allTroopsArray = $starvingTroops = [];
for($i=1;$i<=50;$i++){
$units = $enforce['u'.$i]; $enforceArrays = [$database->getOasisEnforce($starv['wref'], 2),
if($enforce['u'.$i] > $maxcount){ $database->getOasisEnforce($starv['wref'], 3),
$maxcount = $enforce['u'.$i]; $database->getEnforceVillage($starv['wref'], 2),
$maxtype = $i; $database->getEnforceVillage($starv['wref'], 3)];
$enf = $enforce;
} $prisonerArrays = [$database->getPrisoners($starv['wref'], 1)];
$totalunits += $enforce['u'.$i];
} $unitArrays = ($database->getUnitsNumber($starv['wref'], 0) > 0) ? [[$database->getUnit($starv['wref'])]] : [];
if($totalunits == 0 && $enforce['hero'] > 0){
$maxcount = $enforce['hero']; $attackArrays = [$database->getMovement(3, $starv['wref'], 0),
$maxtype = "hero"; $database->getMovement(4, $starv['wref'], 1)];
$heroinfo = $database->getHero($database->getVillageField($enf['from'], "owner"))[0];
$enf = $enforce; $allTroopsArray = [$enforceArrays, $prisonerArrays, $unitArrays, $attackArrays];
}
} // find the first not-empty array
}else{ for($type = 0; $type < count($allTroopsArray); $type++)
//own troops from oasis {
$enforceoasis = $database->getOasisEnforce($starv['wref'], 3); if(!empty($allTroopsArray[$type]))
if(count($enforceoasis)>0){ {
foreach ($enforceoasis as $enforce){ for($subtype = 0; $subtype < count($allTroopsArray[$type]); $subtype++)
for($i = 1; $i <= 50; $i++){ {
$units = $enforce['u'.$i]; if(!empty($allTroopsArray[$type][$subtype]))
if($enforce['u'.$i] > $maxcount){ {
$maxcount = $enforce['u'.$i]; $starvingTroops = reset($allTroopsArray[$type][$subtype]);
$maxtype = $i; break 2;
$enf = $enforce;
}
$totalunits += $enforce['u'.$i];
}
if($totalunits == 0 && $enforce['hero'] > 0){
$maxcount = $enforce['hero'];
$maxtype = "hero";
$heroinfo = $database->getHero($database->getVillageField($enf['from'], "owner"))[0];
$enf = $enforce;
}
}
}else{
//get enforce other player from village
$enforcearray = $database->getEnforceVillage($starv['wref'], 2);
if(count($enforcearray)>0){
foreach ($enforcearray as $enforce){
for($i = 1 ; $i <= 50 ; $i++){
$units = (isset($enforce['u'.$i]) ? $enforce['u'.$i] : 0);
if($units > $maxcount){
$maxcount = $units;
$maxtype = $i;
$enf = $enforce;
}
$totalunits += $units;
}
if($totalunits == 0 && $enforce['hero'] > 0){
$maxcount = $enforce['hero'];
$maxtype = "hero";
$heroinfo = $database->getHero($database->getVillageField($enf['from'], "owner"))[0];
$enf = $enforce;
}
}
}else{
//get own reinforcement from other village
$enforcearray = $database->getEnforceVillage($starv['wref'], 3);
if(count($enforcearray)>0){
foreach ($enforcearray as $enforce){
for($i = 1 ; $i <= 50 ; $i++){
$units = (isset($enforce['u'.$i]) ? $enforce['u'.$i] : 0);
if($units > $maxcount){
$maxcount = $units;
$maxtype = $i;
$enf = $enforce;
}
$totalunits += $units;
}
if($totalunits == 0 && $enforce['hero'] > 0){
$maxcount = $enforce['hero'];
$maxtype = "hero";
$heroinfo = $database->getHero($database->getVillageField($enf['from'], "owner"))[0];
$enf = $enforce;
}
}
}else{
//get own unit
$unitarray = $database->getUnit($starv['wref']);
for($i = 1 ; $i <= 50 ; $i++){
$units = (isset($unitarray['u'.$i]) ? $unitarray['u'.$i] : 0);
if($units > $maxcount){
$maxcount = $units;
$maxtype = $i;
}
$totalunits += $units;
}
if($totalunits == 0){
if($unitarray['hero'] > 0){
$maxcount = $unitarray['hero'];
$maxtype = "hero";
$heroinfo = $database->getHero($starv['owner'])[0];
}else{
//get own travelling troops
$attackarray = $database->getMovement(3, $starv['wref'], 0);
$tribe = $database->getUserField($starv['owner'], "tribe", 0);
foreach ($attackarray as $attack){
for($i = 1 ; $i <= 10; $i++){
$units = (isset($attack['t'.$i]) ? $attack['t'.$i] : 0);
if($units > $maxcount){
$maxcount = $units;
$maxtypeatt = $i;
$maxtype = $maxtypeatt + (($tribe - 1) * 10);
$att = $attack;
}
$totalunits += $units;
}
if($totalunits == 0 && $attack['t11'] > 0){
$maxcount = $attack['t11'];
$maxtype = "hero";
$maxtypeatt = 11;
$heroinfo = $database->getHero($starv['owner'])[0];
$att = $attack;
}
}
}
}
} }
} }
} }
} }
// if the player has no troops, then exit from the function
if(empty($starvingTroops)) continue;
$tribe = $database->getUserField($starv['owner'], "tribe", 0);
$start = ($special = in_array($type, [1, 3])) ? 1 : ($tribe - 1) * 10 + 1;
$end = ($special) ? 10 : $tribe * 10 ;
$utype = ($special) ? 't' : 'u';
$heroType = ($special) ? 't11' : 'hero';
for($i = $start ; $i <= $end ; $i++)
{
$units = (isset($starvingTroops[$utype.$i]) ? $starvingTroops[$utype.$i] : 0);
if($units > $maxcount){
$maxcount = $units;
$maxtype = $i;
}
$totalunits += $units;
}
$totalunits += isset($starvingTroops[$heroType]) ? $starvingTroops[$heroType] : 0;
if($totalunits == 1 && $starvingTroops[$heroType] > 0)
{
$maxcount = $starvingTroops[$heroType];
$maxtype = "hero";
$starvingTroops['heroinfo'] = $database->getHero(($type == 2) ? $starv['owner'] : $database->getVillageField($starvingTroops['from'], "owner"))[0];
}
// counting // counting
$timedif = $time-$starv['starvupdate']; $timedif = $time-$starv['starvupdate'];
@@ -5075,10 +5012,10 @@ class Automation {
if($difcrop > 0) if($difcrop > 0)
{ {
global ${'u'.$maxtype}, ${'h'.$heroinfo['unit'].'_full'}; global ${'u'.$maxtype}, ${'h'.$starvingTroops['heroinfo']['unit'].'_full'};
$hungry = []; $hungry = [];
$hungry = ($maxtype != "hero") ? ${'u'.$maxtype} : ${'h'.$heroinfo['unit'].'_full'}[min($heroinfo['level'], 60)]; $hungry = ($maxtype != "hero") ? ${'u'.$maxtype} : ${'h'.$starvingTroops['heroinfo']['unit'].'_full'}[min($starvingTroops['heroinfo']['level'], 60)];
if ($hungry['crop'] > 0 && $oldcrop <= 0) $killunits = ceil($difcrop/$hungry['crop']); if ($hungry['crop'] > 0 && $oldcrop <= 0) $killunits = ceil($difcrop/$hungry['crop']);
else $killunits = 0; else $killunits = 0;
@@ -5088,32 +5025,41 @@ class Automation {
$pskolko = abs($skolko); $pskolko = abs($skolko);
if($killunits > $pskolko && $skolko < 0) $killunits = $pskolko; if($killunits > $pskolko && $skolko < 0) $killunits = $pskolko;
if($maxtype == "hero" && $maxcount > 0) if($maxtype == "hero" && $totalunits > 0)
{ {
$totalunits = $maxcount; $database->modifyHero("dead", 1, $starvingTroops['heroinfo']['heroid']);
$database->modifyHero("dead", 1, $heroinfo['heroid']); $database->modifyHero("health", 0, $starvingTroops['heroinfo']['heroid']);
$database->modifyHero("health", 0, $heroinfo['heroid']);
} }
if (isset($enf)) switch($type)
{ {
if($killunits < $totalunits) case 0:
{ if($killunits < $totalunits)
$database->modifyEnforce($enf['id'], $maxtype, min($killunits, $maxcount), 0); {
} $database->modifyEnforce($starvingTroops['id'], $maxtype, min($killunits, $maxcount), 0);
else $database->deleteReinf($enf['id']); }
} else $database->deleteReinf($starvingTroops['id']);
elseif(isset($att)) break;
{
if($killunits < $totalunits) case 1:
{ if($killunits < $totalunits)
$database->modifyAttack($att['id'], $maxtypeatt, min($killunits, $maxcount)); {
} $database->modifyPrisoners($starvingTroops['id'], $maxtype, min($killunits, $maxcount), 0);
else $database->setMovementProc($att['moveid']); }
} else $database->deletePrisoners($starvingTroops['id']);
elseif(isset($maxtype)) break;
{
$database->modifyUnit($starv['wref'], [$maxtype], [min($killunits, $maxcount)], [0]); case 2:
$database->modifyUnit($starv['wref'], [$maxtype], [min($killunits, $maxcount)], [0]);
break;
case 3:
if($killunits < $totalunits)
{
$database->modifyAttack($starvingTroops['id'], $maxtype, min($killunits, $maxcount));
}
else $database->setMovementProc($starvingTroops['moveid'].(($subtype == 1) ? ", ".($starvingTroops['moveid'] + 1) : ""));
break;
} }
if($totalunits > 0) if($totalunits > 0)
@@ -5129,7 +5075,7 @@ class Automation {
if ($crop > $upkeep) $database->setVillageField($starv['wref'], ['starv', 'starvupdate'], [0, 0]); if ($crop > $upkeep) $database->setVillageField($starv['wref'], ['starv', 'starvupdate'], [0, 0]);
unset ($starv,$unitarrays,$enforcearray,$enforce,$starvarray,$enf,$att,$attackarray,$maxtype,$maxtypeatt,$heroinfo); unset ($starv, $unitarrays, $enforce, $starvarray, $maxtype, $type, $subtype);
} }
if(file_exists("GameEngine/Prevention/starvation.txt")) { if(file_exists("GameEngine/Prevention/starvation.txt")) {
+25 -3
View File
@@ -5786,17 +5786,18 @@ References: User ID/Message ID, Mode
} }
// no need to cache this method // no need to cache this method
function getUnitsNumber($vid, $use_cache = false) { function getUnitsNumber($vid, $mode = 1, $use_cache = false) {
list( $vid ) = $this->escape_input( (int) $vid ); list( $vid ) = $this->escape_input( (int) $vid );
$dbarray = $this->getUnit( $vid ); $dbarray = $this->getUnit( $vid );
$totalunits = 0; $totalunits = 0;
$movingunits = $this->getVillageMovement( $vid );
for ( $i = 1; $i <= 50; $i ++ ) { for ( $i = 1; $i <= 50; $i ++ ) {
$totalunits += $dbarray[ 'u' . $i ]; $totalunits += $dbarray[ 'u' . $i ];
} }
$totalunits += $dbarray['hero']; $totalunits += $dbarray['hero'];
if(!$mode) return $totalunits;
$movingunits = $this->getVillageMovement( $vid ); $movingunits = $this->getVillageMovement( $vid );
$reinforcingunits = $this->getEnforceArray( $vid, 1 ); $reinforcingunits = $this->getEnforceArray( $vid, 1 );
$owner = $this->getVillageField( $vid, "owner" ); $owner = $this->getVillageField( $vid, "owner" );
@@ -7560,6 +7561,27 @@ References: User ID/Message ID, Mode
return $res; return $res;
} }
/**
* Used to modify prisoners through the inserted id
*
* @param int $id The id where prisoners are in the database
* @param int $unit The type of the unit
* @param int $amount The amount of the unit you want to sum/subtract
* @param int $mode 0 for subtracting the inserted amount, 1 for adding it
* @return bool Returns false on failure and true on success
*/
function modifyPrisoners($id, $unit, $amount, $mode) {
list($id, $unit, $amount, $mode) = $this->escape_input((int) $id,(int) $unit,(int) $amount,(int) $mode);
$unit = 't'.$unit;
$prisoners = $unit." = ".$unit.(!$mode ? " - " : " + ").$amount;
$q = "UPDATE " . TB_PREFIX . "prisoners set $prisoners WHERE id = $id";
$res = mysqli_query($this->dblink,$q);
return $res;
}
function getPrisoners($wid,$mode=0, $use_cache = true) { function getPrisoners($wid,$mode=0, $use_cache = true) {
$array_passed = is_array($wid); $array_passed = is_array($wid);
$mode = (int) $mode; $mode = (int) $mode;