diff --git a/hwe/j_simulate_battle.php b/hwe/j_simulate_battle.php index 768eb47a..e71666a7 100644 --- a/hwe/j_simulate_battle.php +++ b/hwe/j_simulate_battle.php @@ -1,4 +1,5 @@ false, - 'reason'=>'입력값이 없습니다.' + 'result' => false, + 'reason' => '입력값이 없습니다.' ]); } $action = Util::getPost('action'); -if($action === null || !in_array($action, ['reorder', 'battle'])){ +if ($action === null || !in_array($action, ['reorder', 'battle'])) { Json::die([ - 'result'=>false, - 'reason'=>'원하는 동작이 지정되지 않았습니다.' + 'result' => false, + 'reason' => '원하는 동작이 지정되지 않았습니다.' ]); } $query = Json::decode($query); -if($query === null){ +if ($query === null) { Json::die([ - 'result'=>false, - 'reason'=>'올바르지 않은 JSON입니다.' + 'result' => false, + 'reason' => '올바르지 않은 JSON입니다.' ]); } $defaultCheck = [ - 'required'=>[ + 'required' => [ 'attackerGeneral', 'attackerCity', 'attackerNation', 'defenderGenerals', 'defenderCity', 'defenderNation', 'year', 'month', 'repeatCnt' ], - 'integer'=>[ - 'year','month','repeatCnt' + 'integer' => [ + 'year', 'month', 'repeatCnt' ], - 'between'=>[ + 'between' => [ ['month', [1, 12]] ], - 'in'=>[ + 'in' => [ ['repeatCnt', [1, 1000]] ], - 'min'=>[ + 'min' => [ ['year', 0] ], - 'array'=>[ + 'array' => [ 'attackerGeneral', 'attackerCity', 'attackerNation', 'defenderGenerals', 'defenderCity', 'defenderNation' ], @@ -64,10 +65,10 @@ $defaultCheck = [ $v = new Validator($query); $v->rules($defaultCheck); -if(!$v->validate()){ +if (!$v->validate()) { Json::die([ - 'result'=>false, - 'reason'=>$v->errorStr() + 'result' => false, + 'reason' => $v->errorStr() ]); } @@ -86,20 +87,110 @@ $rawDefenderNation = $query['defenderNation']; $warSeed = $query['seed'] ?? ''; +$cityCheck = [ + 'required' => [ + 'city', 'nation', 'supply', 'name', + 'pop', 'agri', 'comm', 'secu', 'def', 'wall', + 'trust', 'level', + 'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max', + 'dead', 'state', 'conflict', + ], + 'numeric' => [ + 'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead' + ], + 'integer' => [ + 'city', 'nation', 'supply', + 'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max', + 'state', + ], + 'min' => [ + ['def', 0], + ['wall', 0], + ['trust', 0], + ['pop', 0], + ['comm', 0], + ['secu', 0], + ['city', 1], + ['nation', 0] + ], + 'in' => [ + ['level', array_keys(getCityLevelList())] + ] +]; + +$v = new Validator($rawAttackerCity); +$v->rules($cityCheck); +if (!$v->validate()) { + Json::die([ + 'result' => false, + 'reason' => '[출병도시]' . $v->errorStr() + ]); +} + +$v = new Validator($rawDefenderCity); +$v->rules($cityCheck); +if (!$v->validate()) { + Json::die([ + 'result' => false, + 'reason' => '[수비도시]' . $v->errorStr() + ]); +} + +$nationCheck = [ + 'required' => [ + 'type', 'tech', 'level', 'capital', + 'nation', 'name', 'gold', 'rice', 'gennum' + ], + 'integer' => [ + 'level', 'capital', 'nation', 'gennum', + ], + 'numeric' => [ + 'tech', 'gold', 'rice' + ], + 'min' => [ + ['tech', 0], + ['gold', 0], + ['rice', 0], + ['gennum', 1], + ], + 'in' => [ + ['type', GameConst::$availableNationType], + ['level', array_keys(getNationLevelList())] + ] +]; + +$v = new Validator($rawAttackerNation); +$v->rules($nationCheck); +if (!$v->validate()) { + Json::die([ + 'result' => false, + 'reason' => '[출병국]' . $v->errorStr() + ]); +} + +$v = new Validator($rawDefenderNation); +$v->rules($nationCheck); +if (!$v->validate()) { + Json::die([ + 'result' => false, + 'reason' => '[수비국]' . $v->errorStr() + ]); +} + $generalCheck = [ - 'required'=>[ + 'required' => [ 'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train', 'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item', 'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'recent_war', 'warnum', 'killnum', 'killcrew', ], - 'integer'=>[ + 'integer' => [ 'no', 'nation', 'crew', 'crewtype', 'atmos', 'train', 'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp', 'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'warnum', 'killnum', 'killcrew', ], - 'min'=>[ + 'min' => [ ['no', 1], ['nation', 1], ['crew', 0], @@ -118,14 +209,14 @@ $generalCheck = [ ['killnum', 0], ['killcrew', 0], ], - 'between'=>[ + 'between' => [ ['train', [40, GameConst::$maxTrainByWar]], ['atmos', [40, GameConst::$maxAtmosByWar]], ['explevel', [0, 300]], ['injury', [0, 80]], ['officer_level', [1, 12]] ], - 'in'=>[ + 'in' => [ ['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)], ['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)], ['crewtype', array_keys(GameUnitConst::all())], @@ -134,11 +225,11 @@ $generalCheck = [ ['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])], ['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])], ], - 'array'=>['inheritBuff'], + 'array' => ['inheritBuff'], ]; $inheritBuffCheck = [ - 'between'=>[ + 'between' => [ [TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]], [TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]], [TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]], @@ -149,49 +240,67 @@ $inheritBuffCheck = [ ] ]; +if(!$warSeed){ + $warSeed = bin2hex(random_bytes(16)); +} +else { + $repeatCnt = 1; +} +$tmpRNG = new RandUtil(new LiteHashDRBG($warSeed)); + $v = new Validator($rawAttacker); $v->rules($generalCheck); -if(!$v->validate()){ +if (!$v->validate()) { Json::die([ - 'result'=>false, - 'reason'=>'[출병자]'.$v->errorStr() + 'result' => false, + 'reason' => '[출병자]' . $v->errorStr() ]); } $rawAttacker['aux'] = []; -if(key_exists('inheritBuff', $rawAttacker)){ +if (key_exists('inheritBuff', $rawAttacker)) { $v = new Validator($rawAttacker['inheritBuff']); $v->rules($inheritBuffCheck); - if(!$v->validate()){ + if (!$v->validate()) { Json::die([ - 'result'=>false, - 'reason'=>'[출병자]'.$v->errorStr() + 'result' => false, + 'reason' => '[출병자]' . $v->errorStr() ]); } $rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff']; } $rawAttacker['aux'] = Json::encode($rawAttacker['aux']); $rawAttacker['owner'] = 0; +$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month); +$attacker = new WarUnitGeneral( + $tmpRNG, + $attackerGeneral, + $rawAttackerNation, + true +); + +/** @var WarUnit[] */ $defenderList = []; -foreach($rawDefenderList as $idx=>$rawDefenderGeneral){ + +foreach ($rawDefenderList as $idx => $rawDefenderGeneral) { $v = new Validator($rawDefenderGeneral); $v->rules($generalCheck); - if(!$v->validate()){ - $idx+=1; + if (!$v->validate()) { + $idx += 1; Json::die([ - 'result'=>false, - 'reason'=>"[수비자{$idx}]".$v->errorStr() + 'result' => false, + 'reason' => "[수비자{$idx}]" . $v->errorStr() ]); } $rawDefenderGeneral['aux'] = []; - if(key_exists('inheritBuff', $rawDefenderGeneral)){ + if (key_exists('inheritBuff', $rawDefenderGeneral)) { $v = new Validator($rawDefenderGeneral['inheritBuff']); $v->rules($inheritBuffCheck); - if(!$v->validate()){ - $idx+=1; + if (!$v->validate()) { + $idx += 1; Json::die([ - 'result'=>false, - 'reason'=>"[수비자{$idx}]".$v->errorStr() + 'result' => false, + 'reason' => "[수비자{$idx}]" . $v->errorStr() ]); } $rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff']; @@ -199,126 +308,41 @@ foreach($rawDefenderList as $idx=>$rawDefenderGeneral){ $rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']); $rawDefenderGeneral['owner'] = 0; - $defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true); + $defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true); + + $defenderList[] = new WarUnitGeneral( + $tmpRNG, + $defenderGeneral, + $rawDefenderNation, + false + ); } +if ($action == 'reorder') { + $noRng = NoRNG::rngInstance(); -$cityCheck = [ - 'required'=>[ - 'city', 'nation', 'supply', 'name', - 'pop', 'agri', 'comm', 'secu', 'def', 'wall', - 'trust', 'level', - 'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max', - 'dead', 'state', 'conflict', - ], - 'numeric'=>[ - 'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead' - ], - 'integer'=>[ - 'city', 'nation', 'supply', - 'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max', - 'state', - ], - 'min'=>[ - ['def', 0], - ['wall', 0], - ['trust', 0], - ['pop', 0], - ['comm', 0], - ['secu', 0], - ['city', 1], - ['nation', 0] - ], - 'in'=>[ - ['level', array_keys(getCityLevelList())] - ] -]; - -$v = new Validator($rawAttackerCity); -$v->rules($cityCheck); -if(!$v->validate()){ - Json::die([ - 'result'=>false, - 'reason'=>'[출병도시]'.$v->errorStr() - ]); -} - -$v = new Validator($rawDefenderCity); -$v->rules($cityCheck); -if(!$v->validate()){ - Json::die([ - 'result'=>false, - 'reason'=>'[수비도시]'.$v->errorStr() - ]); -} - -$nationCheck = [ - 'required'=>[ - 'type', 'tech', 'level', 'capital', - 'nation', 'name', 'gold', 'rice', 'gennum' - ], - 'integer'=>[ - 'level', 'capital', 'nation', 'gennum', - ], - 'numeric'=>[ - 'tech', 'gold', 'rice' - ], - 'min'=>[ - ['tech', 0], - ['gold', 0], - ['rice', 0], - ['gennum', 1], - ], - 'in'=>[ - ['type', GameConst::$availableNationType], - ['level', array_keys(getNationLevelList())] - ] -]; - -$v = new Validator($rawAttackerNation); -$v->rules($nationCheck); -if(!$v->validate()){ - Json::die([ - 'result'=>false, - 'reason'=>'[출병국]'.$v->errorStr() - ]); -} - -$v = new Validator($rawDefenderNation); -$v->rules($nationCheck); -if(!$v->validate()){ - Json::die([ - 'result'=>false, - 'reason'=>'[수비국]'.$v->errorStr() - ]); -} - -$attackerGeneral = new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month); - -if($action == 'reorder'){ - - usort($defenderList, function(General $lhs, General $rhs) use ($attackerGeneral){ - return -(extractBattleOrder($lhs, $attackerGeneral) <=> extractBattleOrder($rhs, $attackerGeneral)); + usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) { + return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker)); }); $order = []; - foreach($defenderList as $defenderGeneral){ - $order[] = $defenderGeneral->getID(); + foreach ($defenderList as $defender) { + $order[] = $defender->getGeneral()->getID(); } Json::die([ - 'result'=>true, - 'reason'=>'success', - 'order'=>$order + 'result' => true, + 'reason' => 'success', + 'order' => $order ]); } -usort($defenderList, function(General $lhs, General $rhs) use ($attackerGeneral){ - return -(extractBattleOrder($lhs, $attackerGeneral) <=> extractBattleOrder($rhs, $attackerGeneral)); +usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) { + return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker)); }); -$rawDefenderList = array_map(function(General $general){ - return $general->getRaw(); +$rawDefenderList = array_map(function (WarUnit $unit) { + return $unit->getRaw(); }, $defenderList); unset($defenderList); @@ -326,11 +350,12 @@ $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); $startYear = $gameStor->startyear; -function extractRankVar(array $rawVal):Map{ +function extractRankVar(array $rawVal): Map +{ $rankVars = new Map; - foreach($rawVal as $rawKey=>$rawVal){ + foreach ($rawVal as $rawKey => $rawVal) { $key = RankColumn::tryFrom($rawKey); - if($key === null){ + if ($key === null) { continue; } $rankVars[$key] = $rawVal; @@ -339,12 +364,19 @@ function extractRankVar(array $rawVal):Map{ } function simulateBattle( - $rawAttacker, $rawAttackerCity, $rawAttackerNation, - $rawDefenderList, $rawDefenderCity, $rawDefenderNation, - $startYear, $year, $month, $warSeed -){ + $rawAttacker, + $rawAttackerCity, + $rawAttackerNation, + $rawDefenderList, + $rawDefenderCity, + $rawDefenderNation, + $startYear, + $year, + $month, + $warSeed +) { - if(!$warSeed){ + if (!$warSeed) { $warSeed = bin2hex(random_bytes(16)); } @@ -359,61 +391,70 @@ function simulateBattle( ); $city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear); - $iterDefender = new \ArrayIterator($rawDefenderList); + /** @var WarUnit[] */ + $defenderList = []; + + foreach ($rawDefenderList as $rawDefenderGeneral) { + $defenderGeneral = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true); + + $defenderList[] = new WarUnitGeneral( + $warRng, + $defenderGeneral, + $rawDefenderNation, + false + ); + } + + $defenderList[] = $city; + + + $iterDefender = new \ArrayIterator($defenderList); $iterDefender->rewind(); $battleResult = []; - $attackerRice = $rawAttacker['rice']; + $attackerRice = $attacker->getGeneral()->getVar('rice'); $defenderRice = 0; - $getNextDefender = function(?WarUnit $prevDefender, bool $reqNext) - use ($warRng, $iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice, $attackerGeneral) { - if($prevDefender !== null){ + $getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) + use ($iterDefender, &$battleResult, &$defenderRice, $attacker): ?WarUnit { + if ($prevDefender !== null) { $prevDefender->getLogger()->rollback(); $battleResult[] = $prevDefender; - if($prevDefender instanceof WarUnitGeneral){ + if ($prevDefender instanceof WarUnitGeneral) { $defenderRice -= $prevDefender->getVar('rice'); } } - if(!$reqNext){ + if (!$reqNext) { return null; } - if(!$iterDefender->valid()){ + if (!$iterDefender->valid()) { return null; } - $defenderObj = new General($iterDefender->current(), extractRankVar($iterDefender->current()), $rawDefenderCity, $rawDefenderNation, $year, $month); - if(extractBattleOrder($defenderObj, $attackerGeneral) <= 0){ + /** @var WarUnit */ + $defender = $iterDefender->current(); + + if (extractBattleOrder($defender, $attacker) <= 0) { return null; } - $defenderRice += $defenderObj->getVar('rice'); + $defenderRice += $defender->getVar('rice'); - $retVal = new WarUnitGeneral( - $warRng, - $defenderObj, - $rawDefenderNation, - false - ); $iterDefender->next(); - return $retVal; + return $defender; }; - $conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city, $year - $startYear); - - $rawDefenderCity = $city->getRaw(); - $updateAttackerNation = []; - $updateDefenderNation = []; + $conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city); $attackerRice -= $attacker->getVar('rice'); - if($city->getPhase() > 0){ + if ($city->getPhase() > 0) { $rice = $city->getKilled() / 100 * 0.8; $rice *= $city->getCrewType()->rice; - $rice *= getTechCost($rawDefenderNation['tech']); + $rice *= getTechCost($city->getRawNation()['tech']); $rice *= $city->getCityTrainAtmos() / 100 - 0.2; Util::setRound($rice); @@ -421,8 +462,8 @@ function simulateBattle( } $totalDead = $attacker->getKilled() + $attacker->getDead(); - $attackerCityDead = $totalDead * 0.4; - $defenderCityDead = $totalDead * 0.6; + //$attackerCityDead = $totalDead * 0.4; + //$defenderCityDead = $totalDead * 0.6; return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice]; } @@ -448,18 +489,26 @@ $avgWar = 0; $attackerActivatedSkills = []; $defendersActivatedSkills = []; -if($warSeed){ - $repeatCnt = 1; -} -foreach(Util::range($repeatCnt) as $repeatIdx){ +foreach (Util::range($repeatCnt) as $repeatIdx) { + if($repeatIdx > 0){ + $warSeed = bin2hex(random_bytes(16)); + } + /** @var WarUnit $attacker */ [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle( - $rawAttacker, $rawAttackerCity, $rawAttackerNation, - $rawDefenderList, $rawDefenderCity, $rawDefenderNation, - $startYear, $year, $month, $warSeed + $rawAttacker, + $rawAttackerCity, + $rawAttackerNation, + $rawDefenderList, + $rawDefenderCity, + $rawDefenderNation, + $startYear, + $year, + $month, + $warSeed ); - $lastWarLog = Util::mapWithKey(function($key, $values){ + $lastWarLog = Util::mapWithKey(function ($key, $values) { return ConvertLog(join('
', $values)); }, $attacker->getLogger()->rollback()); @@ -482,48 +531,45 @@ foreach(Util::range($repeatCnt) as $repeatIdx){ $avgWar += count($battleResult) / $repeatCnt; - foreach($attacker->getActivatedSkillLog() as $skillName => $skillCnt){ - if(!key_exists($skillName, $attackerActivatedSkills)){ + foreach ($attacker->getActivatedSkillLog() as $skillName => $skillCnt) { + if (!key_exists($skillName, $attackerActivatedSkills)) { $attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt; - } - else{ + } else { $attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt; } } - foreach($battleResult as $idx=>$defender){ - while($idx >= count($defendersActivatedSkills)){ + foreach ($battleResult as $idx => $defender) { + while ($idx >= count($defendersActivatedSkills)) { $defendersActivatedSkills[] = []; } $activatedSkills = &$defendersActivatedSkills[$idx]; - foreach($defender->getActivatedSkillLog() as $skillName => $skillCnt){ - if(!key_exists($skillName, $activatedSkills)){ + foreach ($defender->getActivatedSkillLog() as $skillName => $skillCnt) { + if (!key_exists($skillName, $activatedSkills)) { $activatedSkills[$skillName] = $skillCnt / $repeatCnt; - } - else{ + } else { $activatedSkills[$skillName] += $skillCnt / $repeatCnt; } } - } } Json::die([ - 'result'=>true, - 'datetime'=>$rawAttacker['turntime'], - 'reason'=>'success', - 'lastWarLog'=>$lastWarLog, - 'avgWar'=>$avgWar, - 'phase'=>$avgPhase, - 'killed'=>$attackerKilled, - 'maxKilled'=>$attackerMaxKilled, - 'minKilled'=>$attackerMinKilled, - 'dead'=>$attackerDead, - 'maxDead'=>$attackerMaxDead, - 'minDead'=>$attackerMinDead, - 'attackerRice'=>$attackerAvgRice, - 'defenderRice'=>$defenderAvgRice, - 'attackerSkills'=>$attackerActivatedSkills, - 'defendersSkills'=>$defendersActivatedSkills, + 'result' => true, + 'datetime' => $rawAttacker['turntime'], + 'reason' => 'success', + 'lastWarLog' => $lastWarLog, + 'avgWar' => $avgWar, + 'phase' => $avgPhase, + 'killed' => $attackerKilled, + 'maxKilled' => $attackerMaxKilled, + 'minKilled' => $attackerMinKilled, + 'dead' => $attackerDead, + 'maxDead' => $attackerMaxDead, + 'minDead' => $attackerMinDead, + 'attackerRice' => $attackerAvgRice, + 'defenderRice' => $defenderAvgRice, + 'attackerSkills' => $attackerActivatedSkills, + 'defendersSkills' => $defendersActivatedSkills, ]); diff --git a/hwe/process_war.php b/hwe/process_war.php index 2203f97b..62de5e10 100644 --- a/hwe/process_war.php +++ b/hwe/process_war.php @@ -37,16 +37,24 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke $city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear); $defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city')); - $defenderList = General::createGeneralObjListFromDB($defenderIDList, null, 2); + $defenderGeneralList = General::createGeneralObjListFromDB($defenderIDList, null, 2); - usort($defenderList, function (General $lhs, General $rhs) use ($attackerGeneral) { - return - (extractBattleOrder($lhs, $attackerGeneral) <=> extractBattleOrder($rhs, $attackerGeneral)); + /** @var WarUnit[] */ + $defenderList = []; + foreach($defenderGeneralList as $defenderGeneral){ + $defenderList[] = new WarUnitGeneral($rng, $defenderGeneral, $rawDefenderNation, false); + } + + $defenderList[] = $city; + + usort($defenderList, function (WarUnit $lhs, WarUnit $rhs) use ($attacker) { + return - (extractBattleOrder($lhs, $attacker) <=> extractBattleOrder($rhs, $attacker)); }); $iterDefender = new \ArrayIterator($defenderList); $iterDefender->rewind(); - $getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($rng, $iterDefender, $rawDefenderNation, $rawDefenderCity, $db, $attackerGeneral) { + $getNextDefender = function (?WarUnit $prevDefender, bool $reqNext) use ($iterDefender, $db, $attacker) { if ($prevDefender !== null) { $prevDefender->applyDB($db); } @@ -59,24 +67,16 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke return null; } + /** @var WarUnit */ $nextDefender = $iterDefender->current(); - $nextDefender->setRawCity($rawDefenderCity); - if (extractBattleOrder($nextDefender, $attackerGeneral) <= 0) { + if (extractBattleOrder($nextDefender, $attacker) <= 0) { return null; } - - - $retVal = new WarUnitGeneral( - $rng, - $nextDefender, - $rawDefenderNation, - false - ); $iterDefender->next(); - return $retVal; + return $nextDefender; }; - $conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city, $year - $startYear); + $conquerCity = processWar_NG($warSeed, $attacker, $getNextDefender, $city); $attacker->applyDB($db); @@ -180,8 +180,13 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke ], $attacker->getGeneral(), $city->getRaw()); } -function extractBattleOrder(General $general, General $attackerGeneral) +function extractBattleOrder(WarUnit $defender, WarUnit $attacker) { + if($defender instanceof WarUnitCity){ + return -1; + } + + $general = $defender->getGeneral(); if ($general->getVar('crew') == 0) { return 0; } @@ -212,7 +217,6 @@ function processWar_NG( WarUnitGeneral $attacker, callable $getNextDefender, WarUnitCity $city, - int $relYear ): bool { $templates = new \League\Plates\Engine(__DIR__ . '/templates');