mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-08-26 13:17:15 +00:00
This commit is contained in:
@@ -1231,9 +1231,24 @@ trait AutomationBattleResolution {
|
||||
if ($unitlist) {
|
||||
$owndead['hero'] = (isset($battlepart['deadherodef']) ? $battlepart['deadherodef'] : '');
|
||||
|
||||
$unitModifications_units[] = 'hero';
|
||||
$unitModifications_amounts[] = $owndead['hero'];
|
||||
$unitModifications_modes[] = 0;
|
||||
/**
|
||||
* BUG FIXED (issue #379): units.hero ended up at -1.
|
||||
*
|
||||
* The value is still reported (it feeds the battle report and the
|
||||
* points), but it must NOT be subtracted from units.hero here any
|
||||
* more. Battle::applyHeroBattleDamage() already clears the column
|
||||
* itself ("UPDATE units u JOIN vdata v SET u.hero = 0 WHERE
|
||||
* v.owner = <hero owner>") the moment the hero dies, and that runs
|
||||
* inside calculateBattle(), i.e. BEFORE this method.
|
||||
*
|
||||
* So the column went 1 -> 0 there and 0 - 1 -> -1 here: the
|
||||
* village kept showing "-1 Hero" in the troop list while the
|
||||
* Hero's Mansion correctly offered a revive.
|
||||
*
|
||||
* One writer only: the death is owned by applyHeroBattleDamage(),
|
||||
* which is also the only place that knows about the hero's other
|
||||
* possible locations (reinforcements, another village).
|
||||
*/
|
||||
}
|
||||
|
||||
// modify units in DB
|
||||
@@ -1330,10 +1345,21 @@ trait AutomationBattleResolution {
|
||||
}
|
||||
|
||||
if ($enforce['hero'] > 0) {
|
||||
$enforceModificationsById[$enforce['id']]['units'][] = 'hero';
|
||||
$enforceModificationsById[$enforce['id']]['amounts'][] = $battlepart['deadheroref'][$enforce['id']];
|
||||
$enforceModificationsById[$enforce['id']]['modes'][] = 0;
|
||||
|
||||
/**
|
||||
* BUG FIXED (issue #379), same double subtraction as in
|
||||
* applyOwnDefenceCasualties(): a reinforcement hero who died
|
||||
* was already removed by Battle::applyHeroBattleDamage()
|
||||
* ("UPDATE enforcement e JOIN vdata v SET e.hero = 0"), so
|
||||
* subtracting him again here drove enforcement.hero to -1.
|
||||
*
|
||||
* $enforce still reads 1 because getEnforceVillage() answers
|
||||
* from the request cache filled before the battle, so the
|
||||
* stale row hid the problem instead of preventing it.
|
||||
*
|
||||
* The dead count below is kept: it is what the reinforcement
|
||||
* report and $wrong (which decides whether the wiped-out
|
||||
* reinforcement row is deleted) are built from.
|
||||
*/
|
||||
$dead['hero'] = $battlepart['deadheroref'][$enforce['id']];
|
||||
$alldead['hero'] += $dead['hero'];
|
||||
$wrong = $dead['hero'] != $enforce['hero'];
|
||||
|
||||
@@ -614,7 +614,25 @@ trait DatabaseTroopQueries {
|
||||
//Fixed part of negative troops (double troops) - by InCube
|
||||
$array_amt[$i] = (int) $array_amt[$i] < 0 ? 0 : $array_amt[$i];
|
||||
//Fixed part of negative troops (double troops) - by InCube
|
||||
$units .= $unit.' = '.$unit.' '.(($array_mode[$i] == 1)? '+':'-').' '.($array_amt[$i] ? $array_amt[$i] : 0).(($number > $i+1) ? ', ' : '');
|
||||
$amount = (int) ($array_amt[$i] ? $array_amt[$i] : 0);
|
||||
|
||||
/**
|
||||
* The guard above only clamps the AMOUNT, never the RESULT, so any
|
||||
* caller subtracting more than the column holds wrote a NEGATIVE
|
||||
* troop count (issue #379: "-1 Hero" in the village troop list,
|
||||
* after the hero was removed once by Battle::applyHeroBattleDamage()
|
||||
* and a second time by the casualty pipeline).
|
||||
*
|
||||
* A negative troop count is never a valid game state, so floor the
|
||||
* subtraction at 0 in SQL. Additions are untouched.
|
||||
*/
|
||||
if ($array_mode[$i] == 1) {
|
||||
$units .= $unit.' = '.$unit.' + '.$amount;
|
||||
} else {
|
||||
$units .= $unit.' = GREATEST('.$unit.' - '.$amount.', 0)';
|
||||
}
|
||||
|
||||
$units .= (($number > $i+1) ? ', ' : '');
|
||||
}
|
||||
$q = "UPDATE ".TB_PREFIX."units set $units WHERE vref = $vref";
|
||||
return mysqli_query($this->dblink, $q);
|
||||
@@ -881,7 +899,14 @@ trait DatabaseTroopQueries {
|
||||
|
||||
foreach ($unit as $index => $unitType) {
|
||||
$unitType = ($unitType != 'hero' ? 'u' . $this->escape($unitType) : $unitType);
|
||||
$pairs[] = $unitType . ' = ' . $unitType . (!(int) $mode[$index] ? ' - ' : ' + ') . (int) $amt[$index];
|
||||
|
||||
// Same floor as modifyUnit(): a reinforcement column must never go
|
||||
// negative either (issue #379).
|
||||
if ((int) $mode[$index]) {
|
||||
$pairs[] = $unitType . ' = ' . $unitType . ' + ' . (int) $amt[$index];
|
||||
} else {
|
||||
$pairs[] = $unitType . ' = GREATEST(' . $unitType . ' - ' . (int) $amt[$index] . ', 0)';
|
||||
}
|
||||
}
|
||||
|
||||
$q = "UPDATE " . TB_PREFIX . "enforcement SET ".implode(', ', $pairs)." WHERE id = $id";
|
||||
|
||||
Reference in New Issue
Block a user