diff --git a/hwe/func_command.php b/hwe/func_command.php index 9c9ae38c..b4b8c038 100644 --- a/hwe/func_command.php +++ b/hwe/func_command.php @@ -1,6 +1,9 @@ getGeneral()->getID(); + $commandName = $command->getRawClassName(); + $arg = $command->getArg(); + $brief = $command->getBrief(); + $db->update('general_turn', [ - 'action'=>$command, + 'action'=>$commandName, 'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT), 'brief'=>$brief ], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList); } -function _setNationCommand(int $nationID, int $level, array $turnList, string $command, ?array $arg, string $brief) { +function _setNationCommand(NationCommand $command, array $turnList):void { if(!$turnList){ return; } $db = DB::db(); + $nationID = $command->getNationID(); + $level = $command->getGeneralLevel(); + $commandName = $command->getRawClassName(); + $arg = $command->getArg(); + $brief = $command->getBrief(); + $db->update('nation_turn', [ - 'action'=>$command, + 'action'=>$commandName, 'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT), 'brief'=>$brief ], 'nation_id = %i AND level = %i AND turn_idx IN %li', $nationID, $level, $turnList); @@ -313,18 +327,16 @@ function setGeneralCommand(int $generalID, array $rawTurnList, string $command, ]; } - /*if(!$commandObj->isReservable()){ + if(!$commandObj->isReservable()){ return [ 'result'=>false, 'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testReservable(), 'test'=>'isReservable', 'target'=>'command' ]; - }*/ + } - $brief = $commandObj->getBrief(); - - _setGeneralCommand($generalID, $turnList, $command, $arg, $brief); + _setGeneralCommand($commandObj, $turnList); return [ 'result'=>true, 'reason'=>'success' @@ -395,20 +407,20 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr ]; } - /*if(!$commandObj->isReservable()){ + if(!$commandObj->isReservable()){ return [ 'result'=>false, 'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testReservable(), 'test'=>'isReservable', 'target'=>'command' ]; - }*/ + } //TODO: Reservable은 '정말로 입력 불가'이고, '입력은 가능하지만 실행은 안될 것 같은' 군을 하나더 추가해야함 // Runnable은 Arg를 모두 받아서 처리해야 하는 것이고, Arg를 받지 않아도 안될 것 같지만 입력 자체는 가능할 것 같은 커맨드. $brief = $commandObj->getBrief(); - _setNationCommand($general->getNationID(), $general->getVar('level'), $turnList, $command, $arg, $brief); + _setNationCommand($commandObj, $turnList); return [ 'result'=>true, 'arg_test'=>true, diff --git a/hwe/func_gamerule.php b/hwe/func_gamerule.php index 481ded77..21e6dad5 100644 --- a/hwe/func_gamerule.php +++ b/hwe/func_gamerule.php @@ -229,11 +229,23 @@ function updateQuaterly() { $connect=$db->get(); //천도 제한 해제, 관직 변경 제한 해제 - $query = "update nation set capset='0',l12set='0',l11set='0',l10set='0',l9set='0',l8set='0',l7set='0',l6set='0',l5set='0'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $db->update('nation', [ + 'capset'=>0, + 'l12set'=>0, + 'l11set'=>0, + 'l10set'=>0, + 'l9set'=>0, + 'l8set'=>0, + 'l7set'=>0, + 'l6set'=>0, + 'l5set'=>0, + ], true); //관직 변경 제한 해제 - $query = "update city set officer4set='0',officer3set='0',officer2set='0'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $db->update('city', [ + 'officer4set'=>0, + 'officer3set'=>0, + 'officer2set'=>0, + ], true); } // 벌점 감소와 건국제한-1 전턴제한-1 외교제한-1, 1달마다 실행, 병사 있는 장수의 군량 감소, 수입비율 조정 diff --git a/hwe/sammo/Command/BaseCommand.php b/hwe/sammo/Command/BaseCommand.php index c125c632..e9bcdfd5 100644 --- a/hwe/sammo/Command/BaseCommand.php +++ b/hwe/sammo/Command/BaseCommand.php @@ -218,6 +218,17 @@ abstract class BaseCommand{ return $this->arg; } + public function getGeneral():General{ + return $this->generalObj; + } + + public function getNationID(){ + return $this->generalObj->getNationID(); + } + + public function getGeneralLevel(){ + return $this->generalObj->getVar('level'); + } public function getBrief():string{ return static::getName(); diff --git a/hwe/sammo/Command/Nation/che_발령.php b/hwe/sammo/Command/Nation/che_발령.php index 762872f2..a9d3217b 100644 --- a/hwe/sammo/Command/Nation/che_발령.php +++ b/hwe/sammo/Command/Nation/che_발령.php @@ -9,13 +9,15 @@ use \sammo\{ LastTurn, GameUnitConst, CityConst, - Command + Command, + TimeUtil }; use function \sammo\{ getDomesticExpLevelBonus, CriticalRatioDomestic, - CriticalScoreEx + CriticalScoreEx, + function cutTurn }; use \sammo\Constraint\Constraint; @@ -131,7 +133,12 @@ class che_발령 extends Command\NationCommand{ $josaUl = JosaUtil::pick($destGeneralName, '을'); $josaRo = JosaUtil::pick($destCityName, '로'); $destGeneral->getLogger()->pushGeneralActionLog("{$generalName}에 의해 {$destCityName}{$josaRo} 발령됐습니다. <1>$date"); - $destGeneral->setAuxVar('last발령', $general->getTurnTime()); + + $yearMonth = Util::joinYearMonth($this->env['year'], $this->env['month']); + if(cutTurn($general->getTurnTime(), $this->env['turnterm']) != cutTurn($destGeneral->getTurnTime(), $this->env['turnterm'])){ + $yearMonth+=1; + } + $destGeneral->setAuxVar('last발령', $yearMonth); $logger->pushGeneralActionLog("{$destGeneralName}{$josaUl} {$destCityName}{$josaRo} 발령했습니다. <1>$date"); $this->setResultTurn(new LastTurn(static::getName(), $this->arg)); diff --git a/hwe/sammo/GeneralAI.php b/hwe/sammo/GeneralAI.php index 77e21177..afe7f329 100644 --- a/hwe/sammo/GeneralAI.php +++ b/hwe/sammo/GeneralAI.php @@ -65,6 +65,8 @@ class GeneralAI protected $userWarGenerals; /** @var General[] */ protected $userCivilGenerals; + /** @var General[] */ + protected $chiefGenerals; /** @var General[] */ protected $lostGenerals; @@ -96,7 +98,7 @@ class GeneralAI } $this->city = $general->getRawCity(); $this->nation = $db->queryFirstRow( - 'SELECT nation,name,color,capital,capset,gennum,gold,rice,bill,rate,rate_tmp,scout,war,strategic_cmd_limit,surlimit,tech,power,level,type,aux FROM nation WHERE nation = %i', + 'SELECT nation,name,color,capital,capset,gennum,gold,rice,bill,rate,rate_tmp,scout,war,strategic_cmd_limit,surlimit,tech,power,level,l12set,l11set,l10set,l9set,l8set,l7set,l6set,l5set,type,aux FROM nation WHERE nation = %i', $general->getNationID() ) ?? [ 'nation' => 0, @@ -243,6 +245,9 @@ class GeneralAI $this->calcWarRoute(); $troopCandidate = []; + $chiefTurn = cutTurn($this->general->getTurnTime(), $this->env['turnterm']); + $yearMonth = Util::joinYearMonth($this->env['year'], $this->env['month']); + foreach($this->troopLeaders as $troopLeader){ $leaderID = $troopLeader->getID(); if(!key_exists($leaderID, $this->nationPolicy->CombatForce)){ @@ -255,6 +260,19 @@ class GeneralAI continue; } + $last발령 = $troopLeader->getAuxVar('last발령'); + if($last발령){ + $leaderTurn = cutTurn($troopLeader->getTurnTime(), $this->env['turnterm']); + $compYearMonth = $yearMonth; + if($chiefTurn < $leaderTurn){ + $compYearMonth += 1; + } + if($compYearMonth === $yearMonth){ + //한턴마다 한번씩만 발령하자. + continue; + } + } + [$fromCityID, $toCityID] = $this->nationPolicy->CombatForce[$leaderID]; if(!key_exists($fromCityID, $this->warRoute) && !key_exists($toCityID, $this->warRoute)){ @@ -326,6 +344,9 @@ class GeneralAI if(!$this->frontCities){ return null; } + + $chiefTurn = cutTurn($this->general->getTurnTime(), $this->env['turnterm']); + $yearMonth = Util::joinYearMonth($this->env['year'], $this->env['month']); $troopCandidate = []; foreach($this->troopLeaders as $troopLeader){ @@ -344,6 +365,20 @@ class GeneralAI continue; } + $last발령 = $troopLeader->getAuxVar('last발령'); + if($last발령){ + $leaderTurn = cutTurn($troopLeader->getTurnTime(), $this->env['turnterm']); + $compYearMonth = $yearMonth; + if($chiefTurn < $leaderTurn){ + $compYearMonth += 1; + } + if($compYearMonth === $yearMonth){ + //한턴마다 한번씩만 발령하자. + continue; + } + } + + $troopCandidate[$leaderID] = $troopLeader; } @@ -708,8 +743,9 @@ class GeneralAI $cityCandidiates = []; foreach($this->supplyCities as $city){ $dev = min($city['dev'], 0.999); - $score = (1 - $dev)**2; - $score /= \count($city['generals'])+1; + $score = 1 - $dev; + $score **= 2; + $score /= sqrt(count($city['generals']) + 1); $cityCandidiates[$city['city']] = $score; } @@ -924,8 +960,9 @@ class GeneralAI $cityCandidiates = []; foreach($this->supplyCities as $city){ $dev = min($city['dev'], 0.999); - $score = (1 - $dev)**2; - $score /= \count($city['generals'])+1; + $score = 1 - $dev; + $score **= 2; + $score /= sqrt(count($city['generals']) + 1); $cityCandidiates[$city['city']] = $score; } @@ -1667,6 +1704,8 @@ class GeneralAI return $cmd; } } + + return null; } protected function do전쟁내정(GeneralCommand $reservedCommand): ?GeneralCommand @@ -1776,6 +1815,10 @@ class GeneralAI } } + if(!$cmdList){ + return null; + } + return Util::choiceRandomUsingWeightPair($cmdList); } @@ -1943,6 +1986,13 @@ class GeneralAI $type = GameUnitConst::DEFAULT_CREWTYPE; } + if($this->generalPolicy->can고급병종){ + $currType = $general->getCrewTypeObj()->id; + if(key_exists($currType, $typesAll) && $typesAll[$currType][1] >= $typesAll[$type][1]){ + $type = $currType; + } + } + //NOTE: 훈련과 사기진작은 '금만 사용한다'는 가정을 하고 있음 $obj훈련 = buildGeneralCommandClass('che_훈련', $general, $env); $obj사기진작 = buildGeneralCommandClass('che_사기진작', $general, $env); @@ -2125,10 +2175,9 @@ class GeneralAI { $cmd = $reservedCommand; $general = $this->general; - $generalID = $general->getID(); $cmd = buildGeneralCommandClass('che_집합', $general, $this->env); - _setGeneralCommand($generalID, iterator_to_array(Util::range(GameConst::$maxTurn)), $cmd->getRawClassName(), $cmd->getArg(), $cmd->getBrief()); + _setGeneralCommand($cmd, iterator_to_array(Util::range(GameConst::$maxTurn))); return $cmd; } @@ -2140,12 +2189,56 @@ class GeneralAI protected function do거병(GeneralCommand $reservedCommand): ?GeneralCommand { - return null; + $general = $this->general; + // 초반이면서 능력이 좋은놈 위주로 1.4%확률로 거병 + if($general->getVar('makelimit')){ + return null; + } + if(!$this->generalPolicy->can건국){ + return null; + } + + $prop = Util::randF() * (GameConst::$defaultStatNPCMax + GameConst::$chiefStatMin) / 2; + $ratio = ($this->fullLeadership + $this->fullStrength + $this->fullIntel) / 3; + + + if($prop >= $ratio){ + return null; + } + + if(Util::randBool(1 - 0.014)){ + return null; + } + + $cmd = buildGeneralCommandClass('che_거병', $general, $this->env, null); + if(!$cmd->isRunnable()){ + return null; + } + return $cmd; + } + + protected function do해산(GeneralCommand $reservedCommand): ?GeneralCommand + { + $cmd = buildGeneralCommandClass('che_해산', $this->general, $this->env, null); + if(!$cmd->isRunnable()){ + return null; + } + return $cmd; } protected function do건국(GeneralCommand $reservedCommand): ?GeneralCommand { - return null; + $nationType = Util::choiceRandom(GameConst::$availableNationType); + $nationColor = Util::choiceRandom(array_keys(GetNationColors())); + $cmd = buildGeneralCommandClass('che_건국', $this->general, $this->env, [ + 'nationName' => "㉿" . mb_substr($this->general->getName(), 1), + 'nationType' => $nationType, + 'colorType' => $nationColor + ]); + if(!$cmd->isRunnable()){ + return null; + } + return $cmd; } protected function do선양(GeneralCommand $reservedCommand): ?GeneralCommand @@ -2161,8 +2254,6 @@ class GeneralAI $db = DB::db(); - $arg = null; - // 오랑캐는 바로 임관 if ($general->getVar('npc') == 9) { $rulerNation = $db->queryFirstField( @@ -2179,80 +2270,42 @@ class GeneralAI } } - switch (Util::choiceRandomUsingWeight([ - '임관' => 11.4, - '거병_견문' => 40, - '이동' => 20, - '기타' => 28.6 - ])) { - //임관 - case '임관': - - $available = true; - - if ($env['startyear'] + 3 > $env['year']) { - //초기 임관 기간에서는 국가가 적을수록 임관 시도가 적음 - $nationCnt = $db->queryFirstField('SELECT count(nation) FROM nation'); - $notFullNationCnt = $db->queryFirstField('SELECT count(nation) FROM nation WHERE gennum < %i', GameConst::$initialNationGenLimit); - if ($nationCnt == 0 || $notFullNationCnt == 0) { - $available = false; - } else if (Util::randBool(pow(1 / $nationCnt / pow($notFullNationCnt, 3), 1 / 4))) { - //국가가 1개일 경우에는 '임관하지 않음' - $available = false; - } - } - - if ($general->getVar('affinity') == 999 || !$available) { + if(Util::randBool(0.3)){ + if ($env['startyear'] + 3 > $env['year']) { + //초기 임관 기간에서는 국가가 적을수록 임관 시도가 적음 + $nationCnt = $db->queryFirstField('SELECT count(nation) FROM nation'); + $notFullNationCnt = $db->queryFirstField('SELECT count(nation) FROM nation WHERE gennum < %i', GameConst::$initialNationGenLimit); + if ($nationCnt == 0 || $notFullNationCnt == 0) { return null; } - - //랜임 커맨드 입력. - $cmd = buildGeneralCommandClass('che_랜덤임관', $general, $env, ['destNationID' => $rulerNation]); - if(!$cmd->isRunnable()){ - return null; - } - return $cmd; - - break; - case '거병_견문': //거병이나 견문 - // 초반이면서 능력이 좋은놈 위주로 1.4%확률로 거병 - - if($general->getVar('makelimit')){ - return null; - } - - if(!$this->generalPolicy->can건국){ - return null; - } - - $prop = Util::randF() * (GameConst::$defaultStatNPCMax + GameConst::$chiefStatMin) / 2; - $ratio = ($general->getVar('leadership') + $general->getVar('strength') + $general->getVar('intel')) / 3; - - if($prop >= $ratio){ + if (Util::randBool(pow(1 / $nationCnt / pow($notFullNationCnt, 3), 1 / 4))) { + //국가가 1개일 경우에는 '임관하지 않음' return null; } + } - if(Util::randBool(1 - 0.014)){ - return null; - } + if ($general->getVar('affinity') == 999) { + return null; + } - $cmd = buildGeneralCommandClass('che_거병', $general, $env, null); - if(!$cmd->isRunnable()){ - return null; - } - return $cmd; - break; - case '이동': //이동 + //랜임 커맨드 입력. + $cmd = buildGeneralCommandClass('che_랜덤임관', $general, $env, ['destNationID' => $rulerNation]); + if(!$cmd->isRunnable()){ + return null; + } + return $cmd; + } - $paths = array_keys(CityConst::byID($city['city'])->path); + if(Util::randBool(0.2)){ + $paths = array_keys(CityConst::byID($city['city'])->path); - $cmd = buildGeneralCommandClass('che_이동', $general, $env, ['destCityID' => Util::choiceRandom($paths)]); - if(!$cmd->isRunnable()){ - return null; - } - return $cmd; - break; + $cmd = buildGeneralCommandClass('che_이동', $general, $env, ['destCityID' => Util::choiceRandom($paths)]); + if(!$cmd->isRunnable()){ + return null; + } + + return $cmd; } return null; } @@ -2382,6 +2435,7 @@ class GeneralAI $npcCivilGenerals = []; $npcWarGenerals = []; $troopLeaders = []; + $chiefGenerals = []; $nationID = $this->nation['nation']; @@ -2408,6 +2462,11 @@ class GeneralAI $generalID = $nationGeneral->getID(); $cityID = $nationGeneral->getCityID(); $npcType = $nationGeneral->getVar('npc'); + $generalLevel = $nationGeneral->getVar('level'); + + if($generalLevel > 4){ + $chiefGenerals[$generalLevel] = $nationGeneral; + } if (key_exists($cityID, $nationCities)) { $nationCities[$cityID]['generals'][$generalID] = $nationGeneral; @@ -2461,6 +2520,7 @@ class GeneralAI $this->npcCivilGenerals = $npcCivilGenerals; $this->npcWarGenerals = $npcWarGenerals; $this->troopLeaders = $troopLeaders; + $this->chiefGenerals = $chiefGenerals; } @@ -2469,6 +2529,9 @@ class GeneralAI $lastTurn = $reservedCommand->getLastTurn(); $general = $this->general; + $this->categorizeNationGeneral(); + $this->categorizeNationCities(); + if($general->getVar('level') == 12){ $month = $this->env['month']; if (in_array($month, [1, 4, 7, 10])) { @@ -2481,12 +2544,15 @@ class GeneralAI $this->calcRiceBillRate(); } } + else if(in_array($month, [3, 6, 9, 12])){ + $this->calcNonLordPromotion(); + } if($reservedCommand->isRunnable()){ return $reservedCommand; } - $this->categorizeNationGeneral(); + foreach($this->nationPolicy->priority as $actionName){ if(!$this->nationPolicy->{'can'.$actionName}){ @@ -2549,29 +2615,34 @@ class GeneralAI if($result !== null){ return $result; } + return $this->do중립($reservedCommand); } - else { - if($npcType >= 2 && $general->getVar('level') == 12 && !$this->nation['capital']){ - //방랑군 건국 - $result = $this->do건국($reservedCommand); - if($result !== null){ - return $result; - } - $result = $this->do방랑군이동($reservedCommand); - if($result !== null){ - return $result; - } + + if($npcType >= 2 && $general->getVar('level') == 12 && !$this->nation['capital']){ + //방랑군 건국 + $result = $this->do건국($reservedCommand); + if($result !== null){ + return $result; + } + $result = $this->do방랑군이동($reservedCommand); + if($result !== null){ + return $result; } - foreach($this->generalPolicy->priority as $actionName){ - if(!$this->generalPolicy->{'can'.$actionName}){ - continue; - } - /** @var ?GeneralCommand */ - $result = $this->{'do'.$actionName}($reservedCommand); - if($result !== null){ - return $result; - } + $result = $this->do해산($reservedCommand); + if($result !== null){ + return $result; + } + } + + foreach($this->generalPolicy->priority as $actionName){ + if(!$this->generalPolicy->{'can'.$actionName}){ + continue; + } + /** @var ?GeneralCommand */ + $result = $this->{'do'.$actionName}($reservedCommand); + if($result !== null){ + return $result; } } @@ -3087,88 +3158,6 @@ class GeneralAI return Util::choiceRandomUsingWeightPair($commandList); } - public function chooseNeutralTurn(): array - { - - $general = $this->getGeneralObj(); - $city = $this->city; - $env = $this->env; - - $db = DB::db(); - - $arg = null; - - // 오랑캐는 바로 임관 - if ($general->getVar('npc') == 9) { - $rulerNation = $db->queryFirstField( - 'SELECT nation FROM general WHERE `level`=12 AND npc=9 and nation not in %li ORDER BY RAND() limit 1', - $general->getAuxVar('joinedNations') ?? [0] - ); - - if ($rulerNation) { - return ['che_임관', ['destNationID' => $rulerNation]]; - } - return ['che_견문', null]; - } - - switch (Util::choiceRandomUsingWeight([ - '임관' => 11.4, - '거병_견문' => 40, - '이동' => 20, - '기타' => 28.6 - ])) { - //임관 - case '임관': - - $available = true; - - if ($env['startyear'] + 3 > $env['year']) { - //초기 임관 기간에서는 국가가 적을수록 임관 시도가 적음 - $nationCnt = $db->queryFirstField('SELECT count(nation) FROM nation'); - $notFullNationCnt = $db->queryFirstField('SELECT count(nation) FROM nation WHERE gennum < %i', GameConst::$initialNationGenLimit); - if ($nationCnt == 0 || $notFullNationCnt == 0) { - $available = false; - } else if (Util::randBool(pow(1 / $nationCnt / pow($notFullNationCnt, 3), 1 / 4))) { - //국가가 1개일 경우에는 '임관하지 않음' - $available = false; - } - } - - if ($general->getVar('affinity') == 999 || !$available) { - $command = 'che_견문'; //견문 - } else { - //랜임 커맨드 입력. - $command = 'che_랜덤임관'; - $arg = [ - 'destNationIDList' => [] - ]; - } - break; - case '거병_견문': //거병이나 견문 - // 초반이면서 능력이 좋은놈 위주로 1.4%확률로 거병 - $prop = Util::randF() * (GameConst::$defaultStatNPCMax + GameConst::$chiefStatMin) / 2; - $ratio = ($general->getVar('leadership') + $general->getVar('strength') + $general->getVar('intel')) / 3; - if ($env['startyear'] + 2 > $env['year'] && $prop < $ratio && Util::randBool(0.014) && $general->getVar('makelimit') == 0) { - //거병 - $command = 'che_거병'; - } else { - //견문 - $command = 'che_견문'; - } - break; - case '이동': //이동 - - $paths = array_keys(CityConst::byID($city['city'])->path); - $command = 'che_이동'; - $arg = ['destCityID' => Util::choiceRandom($paths)]; - break; - default: - $command = 'che_견문'; - break; - } - return [$command, $arg]; - } - public function old_chooseGeneralTurn($command, $arg): array { $general = $this->getGeneralObj(); @@ -3205,11 +3194,7 @@ class GeneralAI $arg = []; $general->setVar('killturn', rand(70, 75)); //NOTE: 부대 편성에 보여야 하므로 이것만 DB에 직접 접근함. - $db->update('general_turn', [ - 'action' => 'che_집합', - 'arg' => '{}', - 'brief' => '집합' - ], 'general_ID=%i AND turn_idx < 6', $general->getID()); + //_setGeneralCommand($general->getID, [0,1,2,3,4,5], 'che_집합', null, '집합'); } return [$command, $arg]; @@ -3694,6 +3679,50 @@ class GeneralAI return Util::choiceRandomUsingWeight($nations); } + protected function calcNonLordPromotion(){ + //빈자리는 아무나 채움 + $db = DB::db(); + foreach(Util::range(getNationChiefLevel($this->nation['level']), 12) as $chiefLevel){ + if($this->nation["l{$chiefLevel}set"]){ + continue; + } + if(key_exists($chiefLevel, $this->chiefGenerals)){ + continue; + } + + + $picked = false; + foreach(Util::range(5) as $idx){ + /** @var General */ + $randGeneral = Util::choiceRandom($this->npcWarGenerals); + if($chiefLevel == 11){ + $picked = true; + break; + } + + if($chiefLevel % 2 == 0){ + if($randGeneral->getStrength(false, false, false, false) < GameConst::$chiefStatMin){ + continue; + } + } + else{ + if($randGeneral->getIntel(false, false, false, false) < GameConst::$chiefStatMin){ + continue; + } + } + $picked = true; + break; + } + + if(!$picked){ + continue; + } + + $randGeneral->setVar('level', $chiefLevel); + $randGeneral->applyDB($db); + } + } + protected function calcPromotion() { $db = DB::db(); @@ -3712,7 +3741,7 @@ class GeneralAI 'permission' => 'ambassador', ], 'nation=%i AND npc < 2 AND level > 4', $nationID); - foreach ($db->query( + foreach($db->query( 'SELECT no, npc, level, killturn FROM general WHERE nation = %i AND 12 > level AND level > 4', $nationID ) as $chief) { diff --git a/src/sammo/Util.php b/src/sammo/Util.php index a5be3f1d..d8607162 100644 --- a/src/sammo/Util.php +++ b/src/sammo/Util.php @@ -655,6 +655,10 @@ class Util extends \utilphp\util return $year * 12 + $month - 1; } + public static function parseYearMonth(int $yearMonth):array{ + return [intdiv($yearMonth, 12), $yearMonth%12 + 1]; + } + /** * 변수의 값을 첫번째 값부터 비교해서 대소를 반환 * 길이가 다른 경우, 앞의 결과를 먼저 비교한 뒤, 짧은쪽의 값을 null으로 가정하여 길이 처리