diff --git a/hwe/func_process.php b/hwe/func_process.php index 770da377..bc354339 100644 --- a/hwe/func_process.php +++ b/hwe/func_process.php @@ -190,5 +190,9 @@ function CriticalScoreEx(string $type):float { if ($type == 'success') { return Util::randRange(2.2, 3.0); } + if ($type == 'fail') { + return Util::randRange(0.2, 0.4); + } + return 1; } diff --git a/hwe/sammo/Command/BaseCommand.php b/hwe/sammo/Command/BaseCommand.php index 19090ff8..9ae0b1e5 100644 --- a/hwe/sammo/Command/BaseCommand.php +++ b/hwe/sammo/Command/BaseCommand.php @@ -201,10 +201,7 @@ abstract class BaseCommand{ $db = DB::db(); $destNation = $db->queryFirstRow('SELECT %l FROM nation WHERE nation=%i', Util::formatListOfBackticks($args), $nationID); if($destNation === null){ - $destNation = []; - foreach($args as $arg){ - $destNation[$arg] = $defaultValues[$arg]; - } + $destNation = $defaultValues; } $this->destNation = $destNation; } diff --git a/hwe/sammo/Command/General/che_거병.php b/hwe/sammo/Command/General/che_거병.php index 7c2df244..d119ca68 100644 --- a/hwe/sammo/Command/General/che_거병.php +++ b/hwe/sammo/Command/General/che_거병.php @@ -75,6 +75,7 @@ class che_거병 extends Command\GeneralCommand{ $nationName = $generalName; $cityName = $this->city['name']; + $logger = $general->getLogger(); $nationNameExistsCnt = $db->queryFirstField('SELECT count(*) FROM nation WHERE name = %s', $nationName); if($nationNameExistsCnt){ @@ -86,6 +87,20 @@ class che_거병 extends Command\GeneralCommand{ $nationName = '㉥'.$nationName; } + DB::db()->insert('nation', [ + 'name'=>$nationName, + 'color'=>'#330000', + 'gold'=>0, + 'rice'=>GameConst::$baserice, + 'rate'=>20, + 'bill'=>100, + 'strategic_cmd_limit'=>12, + 'surlimit'=>72, + 'type'=>0, + 'gennum'=>1 + ]); + $nationID = DB::db()->insertId(); + $diplomacyInit = []; foreach(getAllNationStaticInfo() as $destNation){ @@ -106,19 +121,7 @@ class che_거병 extends Command\GeneralCommand{ } $db->insert('diplomacy', $diplomacyInit); - DB::db()->insert('nation', [ - 'name'=>$nationName, - 'color'=>'#330000', - 'gold'=>0, - 'rice'=>GameConst::$baserice, - 'rate'=>20, - 'bill'=>100, - 'strategic_cmd_limit'=>12, - 'surlimit'=>72, - 'type'=>0, - 'gennum'=>1 - ]); - $nationID = DB::db()->insertId(); + $turnRows = []; foreach([12, 11] as $chiefLevel){ foreach(range(0, GameConst::$maxChiefTurn - 1) as $turnIdx){ diff --git a/hwe/sammo/Command/General/che_등용.php b/hwe/sammo/Command/General/che_등용.php index a0e3f623..a989e32f 100644 --- a/hwe/sammo/Command/General/che_등용.php +++ b/hwe/sammo/Command/General/che_등용.php @@ -65,7 +65,7 @@ class che_등용 extends Command\GeneralCommand{ $relYear = $this->env['year'] - $this->env['startyear']; $this->runnableConstraints=[ - ConstraintHelper::ReqEnvValue('join_mode', '장수 수', '==', 'onlyRandom', '랜덤 임관만 가능합니다'), + ConstraintHelper::ReqEnvValue('join_mode', '==', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotOpeningPart($relYear), ConstraintHelper::OccupiedCity(), diff --git a/hwe/sammo/Command/General/che_랜덤임관.php b/hwe/sammo/Command/General/che_랜덤임관.php index 6455a938..6ae4a011 100644 --- a/hwe/sammo/Command/General/che_랜덤임관.php +++ b/hwe/sammo/Command/General/che_랜덤임관.php @@ -2,7 +2,7 @@ namespace sammo\Command\General; use \sammo\{ - DB, Util, JosaUtil, TimeUtil, + DB, Util, JosaUtil, TimeUtil, Json, General, ActionLogger, GameConst, GameUnitConst, @@ -33,10 +33,10 @@ class che_랜덤임관 extends Command\GeneralCommand{ $destNationIDList = $this->arg['destNationIDList']??null; //null은 에러, []는 정상 - if($destNationIDList === null || is_array($destNationIDList)){ + if($destNationIDList === null || !is_array($destNationIDList)){ return false; } - if(Util::isDict($destNationIDList)){ + if($destNationIDList && Util::isDict($destNationIDList)){ return false; } foreach($destNationIDList as $nationID){ @@ -66,10 +66,12 @@ class che_랜덤임관 extends Command\GeneralCommand{ $this->runnableConstraints=[ ConstraintHelper::BeNeutral(), - ConstraintHelper::ExistsDestNation(), ConstraintHelper::AllowJoinAction(), - ConstraintHelper::ExistsAllowJoinNation($relYear, $this->arg['destNationIDList']), ]; + + if($this->arg['destNationIDList']){ + $this->runnableConstraints[] = ConstraintHelper::ExistsAllowJoinNation($relYear, $this->arg['destNationIDList']); + } } public function getCost():array{ @@ -103,12 +105,21 @@ class che_랜덤임관 extends Command\GeneralCommand{ $destNation = null; - if ($general->getVar('npc') >= 2 && !$env['fiction'] && 1000 <= $admin['scenario'] && $admin['scenario'] < 2000) { - $nations = $db->query( - 'SELECT nation.`name` as `name`,nation.nation as nation,scout,gennum,`affinity` FROM nation join general on general.nation = nation.nation and general.level = 12 WHERE scout=0 and gennum<%i and nation.nation not in %li', - $notIn, - $relYear<3?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral - ); + if ($general->getVar('npc') >= 2 && !$env['fiction'] && 1000 <= $env['scenario'] && $env['scenario'] < 2000) { + if($notIn){ + $nations = $db->query( + 'SELECT nation.`name` as `name`,nation.nation as nation,scout,gennum,`affinity` FROM nation join general on general.nation = nation.nation and general.level = 12 WHERE scout=0 and gennum<%i and nation.nation not in %li', + $relYear<3?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral, + $notIn + ); + } + else{ + $nations = $db->query( + 'SELECT nation.`name` as `name`,nation.nation as nation,scout,gennum,`affinity` FROM nation join general on general.nation = nation.nation and general.level = 12 WHERE scout=0 and gennum<%i', + $relYear<3?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral + ); + } + shuffle($nations); $allGen = Util::arraySum($nations, 'gennum'); @@ -145,11 +156,20 @@ class che_랜덤임관 extends Command\GeneralCommand{ } $generalsCnt = []; - $rawGeneralsCnt = $db->query( - 'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 5 AND nation.gennum < %i AND nation.nation NOT IN %li GROUP BY general.nation, general.npc', - $genLimit, - $notIn - ); + if($notIn){ + $rawGeneralsCnt = $db->query( + 'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 5 AND nation.gennum < %i AND nation.nation NOT IN %li GROUP BY general.nation, general.npc', + $genLimit, + $notIn + ); + } + else{ + $rawGeneralsCnt = $db->query( + 'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc < 5 AND nation.gennum < %i GROUP BY general.nation, general.npc', + $genLimit + ); + } + foreach($rawGeneralsCnt as $nation){ $nationID = $nation['nation']; @@ -175,7 +195,7 @@ class che_랜덤임관 extends Command\GeneralCommand{ $randVals = []; foreach($generalsCnt as $testNation){ - $randVals[] += [$testNation, 1/$testNation['cnt']]; + $randVals[] = [$testNation, 1/$testNation['cnt']]; } $destNation = Util::choiceRandomUsingWeightPair($randVals); @@ -185,7 +205,6 @@ class che_랜덤임관 extends Command\GeneralCommand{ throw new MustNotBeReachedException(); } - $destNation = $this->destNation; $gennum = $destNation['gennum']; $destNationID = $destNation['nation']; $destNationName = $destNation['name']; @@ -203,7 +222,7 @@ class che_랜덤임관 extends Command\GeneralCommand{ $logger->pushGeneralActionLog("{$destNationName}에 랜덤 임관했습니다. <1>$date"); $logger->pushGeneralHistoryLog("{$destNationName}에 랜덤 임관"); - $logger->pushGlobalActionLog("{$generalName}{$josaYi} {$randomTalk} {$destNationName}임관했습니다."); + $logger->pushGlobalActionLog("{$generalName}{$josaYi} {$randomTalk} {$destNationName}임관했습니다."); if($gennum < GameConst::$initialNationGenLimit) { $exp = 700; @@ -221,7 +240,7 @@ class che_랜덤임관 extends Command\GeneralCommand{ $general->setVar('city', $this->destGeneralObj->getCityID()); } else{ - $targetCityID = $db->queryFirstField('SELECT city FROM nation WHERE nation = %i AND level=12', $destNationID); + $targetCityID = $db->queryFirstField('SELECT city FROM general WHERE nation = %i AND level=12', $destNationID); $general->setVar('city', $targetCityID); } diff --git a/hwe/sammo/Command/General/che_임관.php b/hwe/sammo/Command/General/che_임관.php index 5059ef3f..6496ec26 100644 --- a/hwe/sammo/Command/General/che_임관.php +++ b/hwe/sammo/Command/General/che_임관.php @@ -92,7 +92,7 @@ class che_임관 extends Command\GeneralCommand{ $relYear = $env['year'] - $env['startyear']; $this->runnableConstraints=[ - ConstraintHelper::ReqEnvValue('join_mode', '장수 수', '==', 'onlyRandom', '랜덤 임관만 가능합니다'), + ConstraintHelper::ReqEnvValue('join_mode', '==', 'onlyRandom', '랜덤 임관만 가능합니다'), ConstraintHelper::BeNeutral(), ConstraintHelper::ExistsDestNation(), ConstraintHelper::AllowJoinDestNation($relYear), diff --git a/hwe/sammo/Command/General/휴식.php b/hwe/sammo/Command/General/휴식.php index 87d29da5..eaa586a6 100644 --- a/hwe/sammo/Command/General/휴식.php +++ b/hwe/sammo/Command/General/휴식.php @@ -5,6 +5,7 @@ use \sammo\Command; use \sammo\Util; use \sammo\JosaUtil; use \sammo\LastTurn; +use \sammo\DB; class 휴식 extends Command\GeneralCommand{ static protected $actionName = '휴식'; diff --git a/hwe/sammo/Constraint/ConstraintHelper.php b/hwe/sammo/Constraint/ConstraintHelper.php index fb319e5a..0c7d25a6 100644 --- a/hwe/sammo/Constraint/ConstraintHelper.php +++ b/hwe/sammo/Constraint/ConstraintHelper.php @@ -164,8 +164,8 @@ class ConstraintHelper{ return [__FUNCTION__, $npcType]; } - static function ReqEnvValue($key, string $keyNick, string $comp, $reqVal, string $failMessage):array{ - return [__FUNCTION__, [$key, $keyNick, $comp, $reqVal, $failMessage]]; + static function ReqEnvValue($key, string $comp, $reqVal, string $failMessage):array{ + return [__FUNCTION__, [$key, $comp, $reqVal, $failMessage]]; } static function ReqGeneralAtmosMargin(int $maxAtmos):array{ diff --git a/hwe/sammo/GeneralAI.php b/hwe/sammo/GeneralAI.php index 10df9b05..e7bbf4b9 100644 --- a/hwe/sammo/GeneralAI.php +++ b/hwe/sammo/GeneralAI.php @@ -598,7 +598,7 @@ class GeneralAI{ //타 도시에 있는 '유저장' 발령 foreach($lostGenerals as $lostGeneral){ - if($lostGeneral['npc'] < 2){ + if($lostGeneral->npc < 2){ if(in_array($this->dipState, [self::d직전, self::d전쟁]) && $frontCitiesID){ $selCityID = Util::choiceRandom($frontCitiesID); } @@ -903,11 +903,11 @@ class GeneralAI{ 'destCityID'=>$targetCityID ]], 5]; - if($nationGeneral['npc']<2 && ($workRemain&2)){ + if($nationGeneral->npc<2 && ($workRemain&2)){ $workRemain ^= 2; $commandList[] = [$command, $score]; } - else if($nationGeneral['npc']>=2 && ($workRemain&1)){ + else if($nationGeneral->npc>=2 && ($workRemain&1)){ $workRemain ^= 1; $commandList[] = [$command, $score]; } @@ -922,35 +922,35 @@ class GeneralAI{ if($frontCitiesID && $backupCitiesID){ $workRemain = 3; foreach($nationGenerals as $nationGeneral){ - $generalCity = $nationCities[$nationGeneral['city']]??null; + $generalCity = $nationCities[$nationGeneral->city]??null; if(!$generalCity){ continue; } - if($nationGeneral['crew'] >= 1000){ + if($nationGeneral->crew >= 1000){ continue; } - if($nationGeneral['rice'] < 700 * $tech){ + if($nationGeneral->rice < 700 * $tech){ continue; } if(!$generalCity['front']){ continue; } - if($generalCity['pop'] - 33000 > $nationGeneral['leader']){ + if($generalCity['pop'] - 33000 > $nationGeneral->leader){ continue; } - if($nationGeneral['troop'] != 0){ + if($nationGeneral->troop != 0){ continue; } $score = 5; - if($nationGeneral['npc']<2){ + if($nationGeneral->npc<2){ $score *= 4; } $popTrial = 5; for($popTrial = 0; $popTrial < 5; $popTrial++){ $targetCity = $nationCities[Util::choiceRandom($backupCitiesID)]; - if($targetCity['pop'] < 33000 + $nationGeneral['leader']){ + if($targetCity['pop'] < 33000 + $nationGeneral->leader){ continue; } if (Util::randBool($targetCity['pop'] / $targetCity['pop2'])) { @@ -1035,8 +1035,10 @@ class GeneralAI{ } else{ //랜임 커맨드 입력. - $command = 'che_임관'; - $arg = ['destNationID'=>99]; + $command = 'che_랜덤임관'; + $arg = [ + 'destNationIDList'=>[] + ]; } break; case '거병_견문': //거병이나 견문 @@ -1531,7 +1533,7 @@ class GeneralAI{ $targetCity = []; //NOTE: 최단 거리가 현재 도시에서 '어떻게 가야' 가장 짧은지 알 수가 없으므로, 한칸 간 다음 계산하기로 - foreach(CityConst::byID($general->getVar('city'))->path as $nearCityID){ + foreach(array_keys(CityConst::byID($general->getVar('city'))->path) as $nearCityID){ if(CityConst::byID($nearCityID)->level < 4){ $targetCity[$nearCityID] = 0.5; } @@ -1738,11 +1740,17 @@ class GeneralAI{ while(key_exists($candidate, $promoted)){ $iterCurrentType->next(); + if(!$iterCurrentType->valid()){ + break; + } $candidate = $iterCurrentType->current(); } - $chiefCandidate[$cheifLevel] = $candidate; - $promoted[$candidate] = $cheifLevel; + if($candidate){ + $chiefCandidate[$cheifLevel] = $candidate; + $promoted[$candidate] = $cheifLevel; + } + } foreach($chiefCandidate as $chiefLevel=>$chiefID){ diff --git a/hwe/sammo/Scenario/NPC.php b/hwe/sammo/Scenario/NPC.php index 5239f8a1..e1622a63 100644 --- a/hwe/sammo/Scenario/NPC.php +++ b/hwe/sammo/Scenario/NPC.php @@ -267,10 +267,10 @@ class NPC{ $city = $this->locatedCity; if(is_int($city)){ - $city = CityConst::byID($city)['id']??null; + $city = CityConst::byID($city)->id??null; } else if(is_string($city)){ - $city = CityConst::byName($city)['id']??null; + $city = CityConst::byName($city)->id??null; } if($city === null){ if($nationID == 0 || !CityHelper::getAllNationCities($nationID)){ diff --git a/hwe/sql/schema.sql b/hwe/sql/schema.sql index e1277a6b..8f65f2b5 100644 --- a/hwe/sql/schema.sql +++ b/hwe/sql/schema.sql @@ -51,7 +51,7 @@ CREATE TABLE `general` ( `book` INT(2) NOT NULL DEFAULT '0', `horse` INT(2) NOT NULL DEFAULT '0', `item` INT(2) NOT NULL DEFAULT '0', - `turntime` DATETIME(6) NOT NULL DEFAULT NULL, + `turntime` DATETIME(6) NOT NULL, `recwar` DATETIME(6) NULL DEFAULT NULL, `makelimit` INT(2) NULL DEFAULT '0', `killturn` INT(3) NULL DEFAULT NULL, diff --git a/src/sammo/Util.php b/src/sammo/Util.php index b8735d6d..ddef3528 100644 --- a/src/sammo/Util.php +++ b/src/sammo/Util.php @@ -297,25 +297,31 @@ class Util extends \utilphp\util return $result; } - public static function isDict(&$array) + public static function isDict($array) { + if($array === null){ + return false; + } if (!is_array($array)) { //배열이 아니면 dictionary 조차 아님. return false; } + if(count($array) === 0){ + return true; + } + $idx = 0; - $jmp = 0; - foreach ($array as $key=>$value) { + foreach (array_keys($array) as $key) { if (is_string($key)) { return true; } - if(!$idx + 1 == $key){ - return false; + if($idx !== $key){ + return true; } - $idx = $key; + $idx = $key + 1; } - return true; + return false; } /**