diff --git a/hwe/func_process_chief.php b/hwe/func_process_chief.php index 1a278cf0..f2e45c26 100644 --- a/hwe/func_process_chief.php +++ b/hwe/func_process_chief.php @@ -1907,7 +1907,7 @@ function process_76(&$general) { $date = substr($general['turntime'],11,5); - $admin = $gameStor->getValues(['startyear','year','month','develcost','npccount','turnterm']); + $admin = $gameStor->getValues(['startyear','year','month','develcost','turnterm']); $query = "select nation,supply from city where city='{$general['city']}'"; $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); @@ -1985,7 +1985,7 @@ function process_76(&$general) { //의병추가 $npc = 4; - $npcid = $admin['npccount']; + $npcid = Util::randRangeInt(0, 9999999); for($i=0; $i < $addGenCount; $i++) { // 무장 40%, 지장 40%, 무지장 20% $type = rand() % 10; @@ -2053,7 +2053,6 @@ function process_76(&$general) { $intel = GameConst::$defaultStatNPCMax; } - $npccount = 10000 + $npcid; $affinity = rand() % 150 + 1; $name = "ⓖ의병장{$npcid}"; $picture = 'default.jpg'; @@ -2065,14 +2064,14 @@ function process_76(&$general) { @MYDB_query(" insert into general ( - npcid,npc,npc_org,affinity,name,picture,nation, + npc,npc_org,affinity,name,picture,nation, city,leader,power,intel,experience,dedication, level,gold,rice,crew,crewtype,train,atmos,tnmt, weap,book,horse,turntime,killturn,age,belong,personal,special,specage,special2,specage2,npcmsg, makelimit,bornyear,deadyear, dex0, dex10, dex20, dex30, dex40 ) values ( - '$npccount','$npc','$npc','$affinity','$name','$picture','{$nation['nation']}', + '$npc','$npc','$affinity','$name','$picture','{$nation['nation']}', '{$general['city']}','$leader','$power','$intel','{$avgGen['exp']}','{$avgGen['ded']}', '1','100','100','0','".GameUnitConst::DEFAULT_CREWTYPE."','0','0','0', '0','0','0','$turntime','$killturn','{$avgGen['age']}','1','$personal','0','0','0','0','', @@ -2084,8 +2083,6 @@ function process_76(&$general) { $npcid++; } - //npccount - $gameStor->npccount=$npcid; // 국가보정 if($nation['type'] == 11) { $term3 = Util::round($term3 / 2); } diff --git a/hwe/func_process_personnel.php b/hwe/func_process_personnel.php index eb111376..95f574a2 100644 --- a/hwe/func_process_personnel.php +++ b/hwe/func_process_personnel.php @@ -1,182 +1,6 @@ get(); - - $log = []; - $alllog = []; - $history = []; - $date = substr($general['turntime'],11,5); - - $admin = $gameStor->getValues(['startyear', 'year', 'month', 'scenario', 'fiction']); - - $query = "select nation from city where city='{$general['city']}'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $city = MYDB_fetch_array($result); - - $command = DecodeCommand($general['turn0']); - $where = $command[1]; - - $nation = null; - - $joinedNations = Json::decode($general['nations']); - - // 랜덤임관인 경우 - if($general['npc'] >= 2 && $where >= 98 && !$admin['fiction'] && 1000 <= $admin['scenario'] && $admin['scenario'] < 2000){ - //'사실' 모드에서는 '성향'에 우선을 두되, 장수수, 랜덤에 비중을 둠 - $nations = $db->query( - 'SELECT nation.`name` as `name`,nation.nation as nation,scout,nation.`level` as `level`,gennum,`affinity` FROM nation join general on general.nation = nation.nation and general.level = 12 WHERE nation.nation not in %li and gennum < %i and scout = 0', - $joinedNations, - ($admin['year'] < $admin['startyear']+3)?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral - ); - shuffle($nations); - - $allGen = array_sum(array_map(function($item) { - return $item['gennum']; - }, $nations)); - - $maxScore = 1<<30; - - foreach($nations as $testNation){ - $affinity = abs($general['affinity'] - $testNation['affinity']); - $affinity = min($affinity, abs($affinity - 150)); - - $score = log($affinity + 1, 2);//0~ - - //쉐킷쉐킷 - $score += Util::randF(); - - $score += sqrt($testNation['gennum']/$allGen); - - if($score < $maxScore){ - $maxScore = $score; - $nation = $testNation; - } - } - - } - else if($where >= 98) { - //랜임 - $generals = []; - foreach($db->queryAllLists('SELECT count(no), nation FROM general WHERE npc <= 2 AND nation > 0 GROUP BY nation') as list($cnt, $nation)){ - $generals[$nation] = $cnt; - } - - $allGen = array_sum($generals); - - $nations = $db->query( - 'SELECT nation.`name` as `name`,nation.nation as nation,scout,nation.`level` as `level`,gennum,`injury` FROM nation join general on general.nation = nation.nation and general.level = 12 WHERE nation.nation not in %li and gennum < %i and scout = 0', - $joinedNations, - ($admin['year'] < $admin['startyear']+3)?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral - ); - shuffle($nations); - - $randVals = []; - foreach($nations as $idx=>$testNation){ - // 임관금지없음 국가, 방랑군 제외 - if($where == 98 && $testNation['level'] == 0){ - continue; - } - - $score = 1; - if($admin['startyear']+3 > $admin['year'] && $general['npc'] > 2){ - $score *= sqrt((100-max(30, $testNation['injury']))/100); - } - - $score *= sqrt($allGen/$generals[$testNation['nation']]); - $randVals[$idx] = $score; - } - - if($randVals){ - $nation = $nations[Util::choiceRandomUsingWeight($randVals)]; - } - - } else { - $nation = $db->queryFirstRow('SELECT `name`,nation,scout,`level` FROM nation WHERE nation=%i', $where); - } - - if($nation){ - $gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE nation=%i', $nation['nation']); - $josaUn = JosaUtil::pick($nation['name'], '은'); - } - - if(!$nation) { - $log[] = "●{$admin['month']}월:임관할 국가가 없습니다. 임관 실패. <1>$date"; - } elseif($general['nation'] != 0) { - $log[] = "●{$admin['month']}월:재야가 아닙니다. 임관 실패. <1>$date"; - } elseif($nation['nation'] == 0) { - $log[] = "●{$admin['month']}월:없는 국가입니다. 임관 실패. <1>$date"; - } elseif($nation['level'] == 0 && $gencount >= GameConst::$initialNationGenLimit) { - $log[] = "●{$admin['month']}월:현재 {$nation['name']}{$josaUn} 임관이 제한되고 있습니다. 임관 실패."; - } elseif($admin['year'] < $admin['startyear']+3 && $gencount >= GameConst::$initialNationGenLimit) { - $log[] = "●{$admin['month']}월:현재 {$nation['name']}{$josaUn} 임관이 제한되고 있습니다. 임관 실패."; - } elseif($nation['scout'] == 1 && $general['npc'] != 9) { - $log[] = "●{$admin['month']}월:현재 {$nation['name']}{$josaUn} 임관이 금지되어 있습니다. 임관 실패."; - } elseif($general['makelimit'] > 0 && $general['npc'] != 9) { - $log[] = "●{$admin['month']}월:재야가 된지 12턴이 지나야 합니다. 임관 실패. <1>$date"; - } elseif(in_array($nation['nation'], $joinedNations)) { - $log[] = "●{$admin['month']}월:이미 임관했었던 국가입니다. 임관 실패. <1>$date"; - } else { - $josaYi = JosaUtil::pick($general['name'], '이'); - if($where == 99 || $where == 98) { - $alllog[] = "●{$admin['month']}월:{$general['name']}{$josaYi} 어쩌다보니 {$nation['name']}임관했습니다."; - $log[] = "●{$admin['month']}월:{$nation['name']}에 랜덤으로 임관했습니다. <1>$date"; - pushGeneralHistory($general, "●{$admin['year']}년 {$admin['month']}월:{$nation['name']}에 임관"); - } else { - $alllog[] = "●{$admin['month']}월:{$general['name']}{$josaYi} {$nation['name']}임관했습니다."; - $log[] = "●{$admin['month']}월:{$nation['name']}에 임관했습니다. <1>$date"; - pushGeneralHistory($general, "●{$admin['year']}년 {$admin['month']}월:{$nation['name']}에 임관"); - } - - if($gencount < GameConst::$initialNationGenLimit) { $exp = 700; } - else { $exp = 100; } - $ded = 0; - - // 성격 보정 - $exp = CharExperience($exp, $general['personal']); - $ded = CharDedication($ded, $general['personal']); - - // 군주가 있는 곳으로 이동 - $query = "select city from general where nation='{$nation['nation']}' and level='12'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $king = MYDB_fetch_array($result); - - - // NPC초반시 임관기록 추가 안함 - if($general['npc'] > 1 && $admin['year'] < $admin['startyear']+3) { - } else { - $joinedNations[] = $nation['nation']; - } - - // 국적 바꾸고 등급 일반으로 // 명성 상승 - $db->update('general', [ - 'resturn'=>'SUCCESS', - 'nation'=>$nation['nation'], - 'nations'=>Json::encode($joinedNations), - 'level'=>1, - 'experience'=>$db->sqleval('experience + %i', $exp), - 'city'=>$king['city'], - 'belong'=>1 - ], 'no=%i', $general['no']); - - $db->update('nation', [ - 'gennum'=>$gencount + 1, - ], 'nation=%i', $nation['nation']); - - if($where < 99) { - $log = uniqueItem($general, $log); - } else { - $log = uniqueItem($general, $log, 2); - } - } - - pushGeneralPublicRecord($alllog, $admin['year'], $admin['month']); - pushGenLog($general, $log); -} - function process_29(&$general) { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); @@ -187,7 +11,7 @@ function process_29(&$general) { $history = []; $date = substr($general['turntime'],11,5); - $admin = $gameStor->getValues(['startyear','year','month','develcost','npccount','turnterm','scenario']); + $admin = $gameStor->getValues(['startyear','year','month','develcost','turnterm','scenario']); $query = "select nation,name,level,gennum,scout from nation where nation='{$general['nation']}'"; $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); @@ -360,7 +184,6 @@ function process_29(&$general) { //인재추가 $npc = 3; - $npcid = $admin['npccount']; $npccount = 10000 + $npcid; $affinity = rand() % 150 + 1; $picture = 'default.jpg'; @@ -377,7 +200,6 @@ function process_29(&$general) { $killturn = rand()%480 + 120; $db->insert('general', [ - 'npcid'=>$npccount, 'npc'=>$npc, 'npc_org'=>$npc, 'affinity'=>$affinity, @@ -423,9 +245,6 @@ function process_29(&$general) { $npcid++; - //npccount - $gameStor->npccount=$npcid; - $db->update('nation', [ 'gennum'=>$db->sqleval('gennum + 1'), ], 'nation=%i', $general['nation']); diff --git a/hwe/j_set_general_command.php b/hwe/j_set_general_command.php index 978b9fba..9c9a4ed6 100644 --- a/hwe/j_set_general_command.php +++ b/hwe/j_set_general_command.php @@ -34,6 +34,9 @@ $defaultCheck = [ ], 'min'=>[ ['year', 0] + ], + 'integerArray'=>[ + 'destNationIDList', 'destGeneralIDList' ] ]; diff --git a/hwe/sammo/Command/General/che_랜덤임관.php b/hwe/sammo/Command/General/che_랜덤임관.php new file mode 100644 index 00000000..1cfd97bd --- /dev/null +++ b/hwe/sammo/Command/General/che_랜덤임관.php @@ -0,0 +1,216 @@ +arg['destNationIDList']??null; + //null은 에러, []는 정상 + + if($destNationIDList === null || is_array($destNationIDList)){ + return false; + } + if(Util::isDict($destNationIDList)){ + return false; + } + foreach($destNationIDList as $nationID){ + if(!is_int($nationID)){ + return false; + } + if($nationID < 1){ + return false; + } + } + $this->arg = [ + 'destNationIDList' => $destNationIDList + ]; + + return true; + } + + protected function init(){ + + $general = $this->generalObj; + $env = $this->env; + + $this->setCity(); + $this->setNation(); + + $relYear = $env['year'] - $env['startyear']; + + $this->runnableConstraints=[ + ['BeNeutral'], + ['ExistsDestNation'], + ['AllowJoinAction'], + ['ExistsAllowJoinNation', $relYear, [$this->arg['destNationIDList']]], + ]; + } + + public function getCost():array{ + return [0, 0]; + } + + public function getPreReqTurn():int{ + return 0; + } + + public function getPostReqTurn():int{ + return 0; + } + + public function run():bool{ + if(!$this->isRunnable()){ + throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); + } + + $db = DB::db(); + $env = $this->env; + + $general = $this->generalObj; + $date = substr($general->getVar('turntime'),11,5); + $generalName = $general->getName(); + $josaYi = JosaUtil::pick($generalName, '이'); + + $relYear = $env['year'] - $env['startyear']; + + $notIn = array_merge(Json::decode($general->getVar(['nations'])), $this->arg['destNationIDList']); + + $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 + ); + shuffle($nations); + + $allGen = Util::arraySum($nations, 'gennum'); + + $maxScore = 1<<30; + + $affinity = $general->getVar('affinity'); + + foreach($nations as $testNation){ + $affinity = abs($affinity - $testNation['affinity']); + $affinity = min($affinity, abs($affinity - 150)); + + $score = log($affinity + 1, 2);//0~ + + //쉐킷쉐킷 + $score += Util::randF(); + + $score += sqrt($testNation['gennum']/$allGen); + + if($score < $maxScore){ + $maxScore = $score; + $destNation = $testNation; + } + } + } + else{ + $nations = $db->queryFirstColumn( + 'SELECT nation, name, gennum, scout FROM nation WHERE scout=0 AND gennum < %i AND no NOT IN %li', + $relYear<3?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral, + $notIn + ); + + $allGen = Util::arraySum($nations, 'gennum'); + + $randVals = []; + foreach($nations as $testNation){ + $nationID = $nations['nation']; + $randVals[] = [$testNation, sqrt($allGen/$testNation['gennum'])]; + } + + $destNation = Util::choiceRandomUsingWeightPair($randVals); + } + + if(!$destNation){ + throw new MustNotBeReachedException(); + } + + $destNation = $this->destNation; + $gennum = $destNation['gennum']; + $destNationID = $destNation['nation']; + $destNationName = $destNation['name']; + + $logger = $general->getLogger(); + + $talkList = [ + '어쩌다 보니', + '인연이 닿아', + '발길이 닿는 대로', + '소문을 듣고', + '점괘에 따라', + ]; + $randomTalk = Util::choiceRandom($talkList); + + $logger->pushGeneralActionLog("{$destNationName}에 랜덤 임관했습니다. <1>$date"); + $logger->pushGeneralHistoryLog("{$destNationName}에 랜덤 임관"); + $logger->pushGlobalActionLog("{$generalName}{$josaYi} {$randomTalk} {$destNationName}임관했습니다."); + + if($gennum < GameConst::$initialNationGenLimit) { + $exp = 700; + } + else { + $exp = 100; + } + + $exp = $general->onPreGeneralStatUpdate($general, 'experience', $exp); + $general->setVar('nation', $destNationID); + $general->setVar('level', 1); + $general->setVar('belong', 1); + + if($this->destGeneralObj !== null){ + $general->setVar('city', $this->destGeneralObj->getCityID()); + } + else{ + $targetCityID = $db->queryFirstField('SELECT city FROM nation WHERE nation = %i AND level=12', $destNationID); + $general->setVar('city', $targetCityID); + } + + $db->update('nation', [ + 'gennum'=>$db->sqleval('gennum + 1') + ], 'nation=%i', $destNationID); + + $relYear = $env['year'] - $env['startyear']; + if($general->getVar('npc') == 1 || $relYear >= 3){ + $joinedNations = Join::decode($general->getVar('nations')); + $joinedNations[] = $destNationID; + $general->setVar('nations', Join::encode($joinedNations)); + } + + $general->increaseVar('experience', $exp); + $general->setResultTurn(new LastTurn(static::getName(), $this->arg)); + $general->checkStatChange(); + tryUniqueItemLottery($general, '랜덤 임관'); + $general->applyDB($db); + + return true; + } + + +} \ No newline at end of file diff --git a/hwe/sammo/Command/General/che_인재탐색.php b/hwe/sammo/Command/General/che_인재탐색.php new file mode 100644 index 00000000..bdf29160 --- /dev/null +++ b/hwe/sammo/Command/General/che_인재탐색.php @@ -0,0 +1,272 @@ +arg = null; + return true; + } + + protected function init(){ + + $general = $this->generalObj; + + $this->setNation(['gennum']); + $env = $this->env; + + [$reqGold, $reqRice] = $this->getCost(); + + $this->runnableConstraints=[ + ['NotBeNeutral'], + ['NotWanderingNation'], + ['ReqGeneralGold', $reqGold], + ['ReqGeneralRice', $reqRice], + ]; + + $relYear = $env['year'] - $env['startyear']; + if($relYear < 3 && $this->nation['gennum'] >= GameConst::$initialNationGenLimit){ + $nationName = $this->nation['name']; + $josaUn = JosaUtil::pick($nationName, '은'); + $this->runnableConstraints[] = ['AlwaysFail', "현재 {$nationName}{$josaUn} 탐색이 제한되고 있습니다."]; + } + + } + + public function getCost():array{ + return [$this->env['develcost'], 0]; + } + + public function getPreReqTurn():int{ + return 0; + } + + public function getPostReqTurn():int{ + return 0; + } + + public function run():bool{ + if(!$this->isRunnable()){ + throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); + } + + $db = DB::db(); + $env = $this->env; + + $general = $this->generalObj; + $date = substr($general->getVar('turntime'),11,5); + + $nationID = $general->getNationID(); + + $genCount = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=%i AND npc < 2', $nationID); + $npcCount = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=%i AND npc == 3', $nationID); + $npcOtherCount = $db->queryFirstField('SELECT count(no) FROM general WHERE nation!=%i AND npc == 32', $nationID); + + + $genCount = Util::valueFit($genCount, 1); + $npcCount = Util::valueFit($npcCount, 1); + $npcOtherCountScore = Util::round(sqrt($npcOtherCount + 1)) - 1; + + //TODO: 수식 재 설계 + $randPick = 1 / (sqrt($genCount * $npcCount * $npcCount) + $npcOtherCount); + + $logger = $general->getLogger(); + + if(!Util::randBool($randPick)){ + $logger->pushGeneralActionLog("인재를 찾을 수 없었습니다. <1>$date"); + + $incStat = Util::choiceRandomUsingWeight([ + 'leader2'=>$general->getLeadership(false, false, false, false), + 'power2'=>$general->getPower(false, false, false, false), + 'intel2'=>$general->getIntel(false, false, false, false) + ]); + [$reqGold, $reqRice] = $this->getCost(); + + $exp = 100; + $ded = 70; + + $exp = $general->onPreGeneralStatUpdate($general, 'experience', $exp); + $ded = $general->onPreGeneralStatUpdate($general, 'dedication', $ded); + + $general->increaseVarWithLimit('gold', -$reqGold, 0); + $general->increaseVarWithLimit('rice', -$reqRice, 0); + $general->increaseVar('experience', $exp); + $general->increaseVar('dedication', $ded); + $general->increaseVar($incStat, 1); + $general->setResultTurn(new LastTurn(static::getName(), $this->arg)); + $general->checkStatChange(); + tryUniqueItemLottery($general); + $general->applyDB($db); + return true; + } + //인간적으로 너무 길어서 끊었다! + + $exp = 200; + $ded = 300; + + if($env['scenario'] < 100){ + $pickTypeList = ['무'=>4, '지'=>6]; + } + else{ + $pickTypeList = ['무'=>4, '지'=>4, '무지'=>2]; + } + + $pickType = Util::choiceRandomUsingWeightPair($pickTypeList); + + $mainStat = GameConst::$defaultStatMax - Util::randRangeInt(0, 10); + $otherStat = GameConst::$defaultStatMin + Util::randRangeInt(0, 5); + $subStat = GameConst::$defaultStatTotal - $mainStat - $otherStat; + if($subStat < GameConst::$defaultStatMin){ + $subStat = $otherStat; + $otherStat = GameConst::$defaultStatMin; + $mainStat = GameConst::$defaultStatTotal - $subStat - $otherStat; + if($mainStat){ + throw new \LogicException('기본 스탯 설정값이 잘못되어 있음'); + } + } + + $avgGen = $db->queryFirstRow( + 'SELECT max(leader+power+intel) as lpi, avg(dedication) as ded,avg(experience) as exp, + avg(dex0) as dex0, avg(dex10) as dex10, avg(dex20) as dex20, avg(dex30) as dex30, avg(dex40) as dex40 + from general where nation=%i', + $nationID + ); + + if($pickType == '무'){ + $leader = $subStat; + $power = $mainStat; + $intel = $otherStat; + } + else if($pickType == '지'){ + $leader = $subStat; + $power = $otherStat; + $intel = $mainStat; + } + else{ + $leader = $otherStat; + $power = $subStat; + $intel = $mainStat; + } + + // 국내 최고능치 기준으로 랜덤성 스케일링 + $maxLPI = $avgGen['lpi']; + if($maxLPI > 210) { + $leader *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.6, 0.9); + $power *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.6, 0.9); + $intel *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.6, 0.9); + } elseif($maxLPI > 180) { + $leader *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.75, 0.95); + $power *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.75, 0.95); + $intel *= $avgGen['lpi'] / GameConst::$defaultStatTotal * Util::randRange(0.75, 0.95); + } else { + $leader *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.9, 1); + $power *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.9, 1); + $intel *= $maxLPI / GameConst::$defaultStatTotal * Util::randRange(0.9, 1); + } + $leader = Util::round($leader); + $power = Util::round($power); + $intel = Util::round($intel); + + $isOurNation = $this->nation['scout'] == 0; + + $newNPC = new \sammo\Scenario\NPC( + Util::randRangeInt(1, 150), + \sammo\getRandGenName(), + null, + $isOurNation?$nationID:0, + $general->getCityID(), + $leader, + $power, + $intel, + $isOurNation?1:0, + $env['year'] - 20, + $env['year'] + Util::randRangeInt(10, 50), + null, + null + ); + $newNPC->npc = 3; + $newNPC->setMoney(100, 100); + $newNPC->setExpDed($avgGen['exp'], $avgGen['ded']); + $newNPC->setSpecYear( + Util::round((80 - $age)/12) + $age, + Util::round((80 - $age)/3) + $age + ); + $newNPC->setDex( + $avgGen['dex0'], + $avgGen['dex10'], + $avgGen['dex20'], + $avgGen['dex30'], + $avgGen['dex40'] + ); + + $newNPC->build($this->env); + $npcName = $newNPC->realName; + $josaRa = JosaUtil::pick($npcName, '라'); + + if($isOurNation){ + $scoutType = '영입'; + $db->update('nation', [ + 'gennum'=>$db->sqleval('gennum + 1') + ], 'nation=%i', $nationID); + } + else{ + $scoutType = '발견'; + } + + $generalName = $general->getName(); + $josaYi = JosaUtil::pick($generalName, '이'); + + $logger->pushGeneralActionLog("$npcName{$josaRa}는 인재를 {$scoutType}하였습니다! <1>$date"); + $logger->pushGlobalActionLog("{$generalName}{$josaYi} $npcName{$josaRa}는 인재를 {$scoutType}하였습니다!"); + $logger->pushGeneralHistoryLog("$npcName{$josaRa}는 인재를 {$scoutType}"); + + $incStat = Util::choiceRandomUsingWeight([ + 'leader2'=>$general->getLeadership(false, false, false, false), + 'power2'=>$general->getPower(false, false, false, false), + 'intel2'=>$general->getIntel(false, false, false, false) + ]); + [$reqGold, $reqRice] = $this->getCost(); + + $exp = 200; + $ded = 300; + + $exp = $general->onPreGeneralStatUpdate($general, 'experience', $exp); + $ded = $general->onPreGeneralStatUpdate($general, 'dedication', $ded); + + $general->increaseVarWithLimit('gold', -$reqGold, 0); + $general->increaseVarWithLimit('rice', -$reqRice, 0); + $general->increaseVar('experience', $exp); + $general->increaseVar('dedication', $ded); + $general->increaseVar($incStat, 3); + $general->setResultTurn(new LastTurn(static::getName(), $this->arg)); + $general->checkStatChange(); + tryUniqueItemLottery($general); + $general->applyDB($db); + return true; + + return true; + } + + +} \ No newline at end of file diff --git a/hwe/sammo/Command/General/che_임관.php b/hwe/sammo/Command/General/che_임관.php index fda4d72f..b3cdd774 100644 --- a/hwe/sammo/Command/General/che_임관.php +++ b/hwe/sammo/Command/General/che_임관.php @@ -66,6 +66,7 @@ class che_임관 extends Command\GeneralCommand{ protected function init(){ $general = $this->generalObj; + $env = $this->env; $this->setCity(); $this->setNation(); @@ -80,7 +81,7 @@ class che_임관 extends Command\GeneralCommand{ $this->setDestNation($destNationID, ['gennum', 'scout']); } - $relYear = $env['year'] = $env['startyear']; + $relYear = $env['year'] - $env['startyear']; $this->runnableConstraints=[ ['BeNeutral'], @@ -150,7 +151,7 @@ class che_임관 extends Command\GeneralCommand{ 'gennum'=>$db->sqleval('gennum + 1') ], 'nation=%i', $destNationID); - $relYear = $env['year'] = $env['startyear']; + $relYear = $env['year'] - $env['startyear']; if($general->getVar('npc') == 1 || $relYear >= 3){ $joinedNations = Join::decode($general->getVar('nations')); $joinedNations[] = $destNationID; diff --git a/hwe/sammo/Command/General/che_장비매매.php b/hwe/sammo/Command/General/che_장비매매.php index df5b3fb5..4e2c71a2 100644 --- a/hwe/sammo/Command/General/che_장비매매.php +++ b/hwe/sammo/Command/General/che_장비매매.php @@ -75,10 +75,10 @@ class che_장비매매 extends Command\GeneralCommand{ $this->runnableConstraints[] = ['ReqGeneralValue', $itemType, $itemTypeName, 1]; } else if($itemCode == $general->getVar($itemType)){ - $this->runnableConstraints = [['AlwaysFail', '이미 가지고 있습니다.']]; + $this->runnableConstraints[] = ['AlwaysFail', '이미 가지고 있습니다.']; } else if($itemType != 'item' && $general->getVar($itemType) > 6){ - $this->runnableConstraints[] = [['AlwaysFail', '이미 진귀한 것을 가지고 있습니다.']]; + $this->runnableConstraints[] = ['AlwaysFail', '이미 진귀한 것을 가지고 있습니다.']; } } diff --git a/hwe/sammo/Constraint/ExistsAllowJoinNation.php b/hwe/sammo/Constraint/ExistsAllowJoinNation.php new file mode 100644 index 00000000..aabc5f3c --- /dev/null +++ b/hwe/sammo/Constraint/ExistsAllowJoinNation.php @@ -0,0 +1,59 @@ +general)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require nations in nation"); + } + + if(!is_int($this->arg[0])){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("first arg must be int(relYear)"); + } + + if(!is_array($this->arg[1])){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("first arg must be array(exludeList)"); + } + + $this->relYear = $this->arg; + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + $db = DB::db(); + + $relYear = $this->arg[0]; + $notIn = array_merge(Json::decode($this->general['nations']), $this->arg[1]); + //이걸 호출하는 경우 분명 동일한 쿼리를 한번 더 부를 것. 쿼리 캐시를 기대함 + $nations = $db->queryFirstColumn( + 'SELECT nation, name, gennum, scout FROM nation WHERE scout=0 AND gennum < %i AND no NOT IN %li', + $relYear<3?GameConst::$initialNationGenLimit:GameConst::$defaultMaxGeneral, + $notIn + ); + + if($nations){ + return true; + } + + $this->reason = "임관할 국가가 없습니다."; + return false; + } +} \ No newline at end of file diff --git a/hwe/sammo/Constraint/ReqGeneralValue.php b/hwe/sammo/Constraint/ReqGeneralValue.php index 5fe91d0c..93827f8a 100644 --- a/hwe/sammo/Constraint/ReqGeneralValue.php +++ b/hwe/sammo/Constraint/ReqGeneralValue.php @@ -5,6 +5,9 @@ namespace sammo\Constraint; use \sammo\JosaUtil; use \sammo\Util; +/** + * 범용으로 사용 가능한 장수 변수 검사도구 + */ class RegGeneralValue extends Constraint{ const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_ARRAY_ARG; @@ -18,13 +21,26 @@ class RegGeneralValue extends Constraint{ return false; } - [$this->key, $this->keyNick, $this->reqVal] = $this->arg; + if(count($this->arg) == 4){ + [$this->key, $this->keyNick, $comp, $this->reqVal] = $this->arg; + + if(!in_array($comp, ['>', '>=', '==', '<=', '<', '!='])){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("invalid comparator"); + } + } + else{ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require key, keyNick, comp, reqVal"); + } + + $this->comp = $comp; $this->maxKey = $this->key.'2'; - if(!key_exists($this->key, $this->city)){ + if(!key_exists($this->key, $this->general)){ if(!$throwExeception){return false; } - throw new \InvalidArgumentException("require {$this->key} in city"); + throw new \InvalidArgumentException("require {$this->key} in general"); } if(is_numeric($this->reqVal)){ @@ -37,7 +53,7 @@ class RegGeneralValue extends Constraint{ throw new \InvalidArgumentException("require valid reqVal(percentStr|numeric) format"); } - if(!key_exists($this->maxKey, $this->city)){ + if(!key_exists($this->maxKey, $this->general)){ if(!$throwExeception){return false; } throw new \InvalidArgumentException("require {$this->maxKey} in general"); } @@ -51,26 +67,53 @@ class RegGeneralValue extends Constraint{ $this->checkInputValues(); $this->tested = true; - if($this->isPercent){ - if($this->general[$this->key] >= $this->general[$this->maxKey] * $this->reqVal){ - return true; - } - + if ($this->isPercent) { + $reqVal = $this->general[$this->maxKey] * $this->reqVal; } else{ - if($this->general[$this->key] >= $this->reqVal){ - return true; - } + $reqVal = $this->reqVal; } - if($this->reqVal === 1){ - $josaYi = JosaUtil::pick($keyNick, '이'); - $this->reason = "{$keyNick}{$josaUn} 없습니다."; - } - else{ - $josaYi = JosaUtil::pick($keyNick, '이'); - $this->reason = "{$keyNick}{$josaUn} 부족합니다."; + $compList = [ + '<'=>function($target, $src){ + return ($target < $src)?true:'너무 많습니다.'; + }, + '<='=>function($target, $src){ + return ($target <= $src)?true:'너무 많습니다.'; + }, + '=='=>function($target, $src)use($keyNick){ + return ($target == $src)?true:"올바르지 않은 {$keyNick} 입니다."; + }, + '!='=>function($targeta, $src)use($keyNick){ + return ($target == $src)?true:"올바르지 않은 {$keyNick} 입니다."; + }, + '>='=>function($target, $src){ + if($target >= $src){ + return true; + } + if($src == 1){ + return '없습니다'; + } + return '부족합니다.'; + }, + '>'=>function($target, $src){ + return $target >= $src; + if($src == 0){ + return '없습니다'; + } + return '부족합니다.'; + }, + ]; + + $comp = $compList[$this->comp]; + $result = ($comp)($this->general[$this->key], $reqVal); + + if($result === true){ + return true; } + + $josaYi = JosaUtil::pick($keyNick, '이'); + $this->reason = "{$keyNick}{$josaYi} {$result}"; return false; } diff --git a/hwe/sammo/Constraint/ReqNationValue.php b/hwe/sammo/Constraint/ReqNationValue.php new file mode 100644 index 00000000..89f5c5ea --- /dev/null +++ b/hwe/sammo/Constraint/ReqNationValue.php @@ -0,0 +1,120 @@ +arg) == 4){ + [$this->key, $this->keyNick, $this->reqVal, $comp] = $this->arg; + + if(!in_array($comp, ['>', '>=', '==', '<=', '<', '!='])){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("invalid comparator"); + } + } + else{ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require key, keyNick, comp, reqVal"); + } + + $this->comp = $comp; + + $this->maxKey = $this->key.'2'; + + if(!key_exists($this->key, $this->nation)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require {$this->key} in nation"); + } + + if(is_numeric($this->reqVal)){ + $this->isPercent = false; + } + else if(is_str($this->reqVal)){ + $this->reqVal = Util::convPercentStrToFloat($this->reqVal); + if($this->reqVal === null){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require valid reqVal(percentStr|numeric) format"); + } + + if(!key_exists($this->maxKey, $this->nation)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require {$this->maxKey} in nation"); + } + $this->isPercent = true; + } + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + if ($this->isPercent) { + $reqVal = $this->nation[$this->maxKey] * $this->reqVal; + } + else{ + $reqVal = $this->reqVal; + } + + $compList = [ + '<'=>function($target, $src){ + return ($target < $src)?true:'너무 많습니다.'; + }, + '<='=>function($target, $src){ + return ($target <= $src)?true:'너무 많습니다.'; + }, + '=='=>function($target, $src)use($keyNick){ + return ($target == $src)?true:"올바르지 않은 {$keyNick} 입니다."; + }, + '!='=>function($targeta, $src)use($keyNick){ + return ($target == $src)?true:"올바르지 않은 {$keyNick} 입니다."; + }, + '>='=>function($target, $src){ + if($target >= $src){ + return true; + } + if($src == 1){ + return '없습니다'; + } + return '부족합니다.'; + }, + '>'=>function($target, $src){ + return $target >= $src; + if($src == 0){ + return '없습니다'; + } + return '부족합니다.'; + }, + ]; + + $comp = $compList[$this->comp]; + $result = ($comp)($this->nation[$this->key], $reqVal); + + if($result === true){ + return true; + } + + $josaYi = JosaUtil::pick($keyNick, '이'); + $this->reason = "{$keyNick}{$josaYi} {$result}"; + + return false; + } +} \ No newline at end of file diff --git a/hwe/sammo/General.php b/hwe/sammo/General.php index d1e41af4..95454423 100644 --- a/hwe/sammo/General.php +++ b/hwe/sammo/General.php @@ -541,7 +541,7 @@ class General implements iAction{ 'leader', 'leader2', 'power', 'power2', 'intel', 'intel2', 'weap', 'book', 'horse', 'item', 'experience', 'dedication', 'level', 'gold', 'rice', 'crew', 'crewtype', 'train', 'atmos', 'turntime', 'makenation', 'makelimit', 'killturn', 'block', 'dedlevel', 'explevel', 'age', 'belong', - 'personal', 'special', 'special2', 'term', 'mode', 'npc', 'npc_org', 'npcid', 'deadyear', 'npcmsg', + 'personal', 'special', 'special2', 'term', 'mode', 'npc', 'npc_org', 'deadyear', 'npcmsg', 'dex0', 'dex10', 'dex20', 'dex30', 'dex40', 'warnum', 'killnum', 'deathnum', 'killcrew', 'deathcrew', 'recwar', 'last_turn' ]; diff --git a/hwe/sammo/Scenario/NPC.php b/hwe/sammo/Scenario/NPC.php index 676155ad..5b9efa6b 100644 --- a/hwe/sammo/Scenario/NPC.php +++ b/hwe/sammo/Scenario/NPC.php @@ -5,6 +5,9 @@ use \sammo\JosaUtil; use \sammo\DB; use \sammo\CityHelper; use \sammo\GameUnitConst; +use \sammo\CityConst; +use \sammo\GameConst; +use \sammo\SpecialityConst; class NPC{ @@ -24,7 +27,7 @@ class NPC{ public $death; public $ego; public $charDomestic; - public $charWar = 0; + public $charWar; public $npc = 2; public $text; static $prefixList = [ @@ -38,13 +41,27 @@ class NPC{ 9 => 'ⓞ', //오랑캐? ]; - //[ 1, "헌제",1002, 1, null, 17, 13, 61, 0, 170, 250, "안전", null, "산 넘어 산이로구나..."], + protected $gold = 1000; + protected $rice = 1000; + + protected $specAge = null; + protected $specAge2 = null; + protected $experience = null; + protected $dedication = null; + + //XXX: 코드 못 바꾸나? + protected $dex0 = 0; + protected $dex10 = 0; + protected $dex20 = 0; + protected $dex30 = 0; + protected $dex40 = 0; + public function __construct( int $affinity, string $name, $picturePath, int $nationID, - $locatedCity, //FIXME: 7.1로 올릴 때 ?string 으로 변경 + $locatedCity, int $leadership, int $power, int $intel, @@ -75,20 +92,21 @@ class NPC{ 'intel'=>$intel ]; - $this->charDomestic = \sammo\GameConst::$defaultSpecialDomestic; + $this->charDomestic = GameConst::$defaultSpecialDomestic; + $this->charWar = GameConst::$defaultSpecialWar; if($char === '랜덤전특'){ - $this->charWar = \sammo\SpecialityConst::pickSpecialWar($general); + $this->charWar = SpecialityConst::pickSpecialWar($general); } else if($char === '랜덤내특'){ - $this->charDomestic = \sammo\SpecialityConst::pickSpecialDomestic($general); + $this->charDomestic = SpecialityConst::pickSpecialDomestic($general); } else if($char === '랜덤'){ if(Util::randBool(2/3)){ - $this->charWar = \sammo\SpecialityConst::pickSpecialWar($general); + $this->charWar = SpecialityConst::pickSpecialWar($general); } else{ - $this->charDomestic = \sammo\SpecialityConst::pickSpecialDomestic($general); + $this->charDomestic = SpecialityConst::pickSpecialDomestic($general); } } else if($char !== null){ @@ -101,11 +119,38 @@ class NPC{ $this->charDomestic = Util::getClassName($domesticClass); } catch (Exception $e) { - $this->charWar = \sammo\SpecCall($char); + $warClass = \sammo\getGeneralSpecialWarClass($char); + $this->charWar = Util::getClassName($domesticClass); } } } + public function setSpecYear(?int $specAge, ?int $specAge2):self{ + $this->specAge = $specAge; + $this->specAge2 = $specAge2; + return $this; + } + + public function setExpDed(?int $experience, ?int $dedication):self{ + $this->experience = $experience; + $this->dedication = $dedication; + return $this; + } + + public function setMoney(int $gold, int $rice):self{ + $this->gold = $gold; + $this->rice = $rice; + return $this; + } + + public function setDex(int $footman, int $archer, int $cavalry, int $wizard, int $siege):self{ + $this->dex0 = $footman; + $this->dex10 = $archer; + $this->dex20 = $cavalry; + $this->dex30 = $wizard; + $this->dex40 = $siege; + } + public function build($env=[]){ //scenario에 life==1인 경우 수명 제한이 없어지는 모양. @@ -131,11 +176,11 @@ class NPC{ if($this->death <= $year){ return true; //죽었으니 넘어간다. } - if($age < \sammo\GameConst::$adultAge){ + if($age < GameConst::$adultAge){ return false; //예약. } - $isNewGeneral = ($age == \sammo\GameConst::$adultAge); + $isNewGeneral = ($age == GameConst::$adultAge); $nationID = $this->nationID; if($isFictionMode && $isNewGeneral){ @@ -171,11 +216,24 @@ class NPC{ } if($isFictionMode){ - $charWar = 0; + $charWar = GameConst::$defaultSpecialWar; $charDomestic = GameConst::$defaultSpecialDomestic; } $name = (static::$prefixList[$this->npc]?:'ⓧ').$this->name; + + $duplicateCnt = $db->queryFirstField('SELECT count(no) FROM general WHERE name LIKE %s', $name.'%') + 1; + + if($duplicateCnt > 1){ + $name = "{$name}($duplicateCnt}"; + } + $this->realName = $name; + + $query = "select no from general where name like '{$name}%'"; + $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $count = MYDB_num_rows($result); + $count++; + $this->realName = $name; $picturePath = $this->picturePath; @@ -211,8 +269,11 @@ class NPC{ } $city = $this->locatedCity; - if($city !== null){ - $city = CityHelper::getCityByName($city)['id']??null; + if(is_int($city)){ + $city = CityConst::byID($city)['id']??null; + } + else if(is_string($city)){ + $city = CityConst::byName($city)['id']??null; } if($city === null){ if($nationID == 0 || !CityHelper::getAllNationCities($nationID)){ @@ -226,8 +287,8 @@ class NPC{ } - $experience = $age * 100; - $dedication = $age * 100; + $experience = $this->experience?:$age * 100; + $dedication = $this->dedication?:$age * 100; $level = $this->level; if(!$level || $isNewGeneral){ $level = $nationID?1:0; @@ -237,13 +298,10 @@ class NPC{ $killturn = ($this->death - $year) * 12 + mt_rand(0, 11); - $specage = $age + 1; - $specage2 = $age + 1; - - $npcID = $db->queryFirstField('SELECT max(npcid)+1 FROM general'); + $specage = $this->specAge?:$age + 1; + $specage2 = $this->specAge2?:$age + 1; $db->insert('general',[ - 'npcid'=>$npcID, 'npc'=>$this->npc, 'npc_org'=>$this->npc, 'affinity'=>$affinity, @@ -257,8 +315,8 @@ class NPC{ 'experience'=>$experience, 'dedication'=>$dedication, 'level'=>$level, - 'gold'=>1000, - 'rice'=>1000, + 'gold'=>$this->gold, + 'rice'=>$this->rice, 'crew'=>0, 'crewtype'=>GameUnitConst::DEFAULT_CREWTYPE, 'train'=>0, @@ -278,7 +336,12 @@ class NPC{ 'npcmsg'=>$this->text, 'makelimit'=>0, 'bornyear'=>$this->birth, - 'deadyear'=>$this->death + 'deadyear'=>$this->death, + 'dex0'=>$this->dex0, + 'dex10'=>$this->dex10, + 'dex20'=>$this->dex20, + 'dex30'=>$this->dex30, + 'dex40'=>$this->dex40, ]); $this->generalID = $db->insertId(); diff --git a/hwe/sammo/SpecialityConst.php b/hwe/sammo/SpecialityConst.php index dd66f49a..aff9b1f7 100644 --- a/hwe/sammo/SpecialityConst.php +++ b/hwe/sammo/SpecialityConst.php @@ -43,43 +43,43 @@ class SpecialityConst{ ]; const WAR = [ - 40 => ['귀병', 1, [self::STAT_INTEL | self::ARMY_WIZARD | self::REQ_DEXTERITY]], + 'che_귀병' => ['귀병', 1, [self::STAT_INTEL | self::ARMY_WIZARD | self::REQ_DEXTERITY]], - 41 => ['신산', 1, [self::STAT_INTEL]], - 42 => ['환술', -5, [self::STAT_INTEL]], - 43 => ['집중', 1, [self::STAT_INTEL]], - 44 => ['신중', 1, [self::STAT_INTEL]], - 45 => ['반계', 1, [self::STAT_INTEL]], + 'che_신산' => ['신산', 1, [self::STAT_INTEL]], + 'che_환술' => ['환술', -5, [self::STAT_INTEL]], + 'che_집중' => ['집중', 1, [self::STAT_INTEL]], + 'che_신중' => ['신중', 1, [self::STAT_INTEL]], + 'che_반계' => ['반계', 1, [self::STAT_INTEL]], - 50 => ['보병', 1, [ + 'che_보병' => ['보병', 1, [ self::STAT_LEADERSHIP | self::REQ_DEXTERITY | self::ARMY_FOOTMAN, self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_FOOTMAN ]], - 51 => ['궁병', 1, [ + 'che_궁병' => ['궁병', 1, [ self::STAT_LEADERSHIP | self::REQ_DEXTERITY | self::ARMY_ARCHER, self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_ARCHER ]], - 52 => ['기병', 1, [ + 'che_기병' => ['기병', 1, [ self::STAT_LEADERSHIP | self::REQ_DEXTERITY | self::ARMY_CAVALRY, self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_CAVALRY ]], - 53 => ['공성', 1, [ + 'che_공성' => ['공성', 1, [ self::STAT_LEADERSHIP | self::REQ_DEXTERITY | self::ARMY_SIEGE, self::STAT_POWER | self::REQ_DEXTERITY | self::ARMY_SIEGE, self::STAT_INTEL | self::REQ_DEXTERITY | self::ARMY_SIEGE ]], - 60 => ['돌격', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], - 61 => ['무쌍', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], - 62 => ['견고', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], - 63 => ['위압', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], + 'che_돌격' => ['돌격', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], + 'che_무쌍' => ['무쌍', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], + 'che_견고' => ['견고', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], + 'che_위압' => ['위압', 1, [self::STAT_LEADERSHIP, self::STAT_POWER]], - 70 => ['저격', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], - 71 => ['필살', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], - 72 => ['징병', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], - 73 => ['의술', -2, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], - 74 => ['격노', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], - 75 => ['척사', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], + 'che_저격' => ['저격', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], + 'che_필살' => ['필살', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], + 'che_징병' => ['징병', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], + 'che_의술' => ['의술', -2, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], + 'che_격노' => ['격노', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], + 'che_척사' => ['척사', 1, [self::STAT_LEADERSHIP, self::STAT_POWER, self::STAT_INTEL]], ]; public static function getInvDomestic(string $name){ @@ -206,7 +206,7 @@ class SpecialityConst{ throw new MustNotBeReachedException(); } - public static function pickSpecialWar(array $general) : int{ + public static function pickSpecialWar(array $general) : string{ $reqDex = []; $pAbs = []; $pRel = []; diff --git a/hwe/sql/schema.sql b/hwe/sql/schema.sql index c1bab5c4..ef5bf7d3 100644 --- a/hwe/sql/schema.sql +++ b/hwe/sql/schema.sql @@ -6,7 +6,6 @@ CREATE TABLE `general` ( `no` INT(11) NOT NULL AUTO_INCREMENT, `owner` INT(11) NOT NULL DEFAULT '0', `npcmsg` CHAR(255) NULL DEFAULT '', - `npcid` INT(5) NULL DEFAULT NULL, `npc` INT(1) NULL DEFAULT '0', `npc_org` INT(1) NULL DEFAULT '0', `affinity` INT(3) NULL DEFAULT '0', @@ -131,9 +130,9 @@ CREATE TABLE `general` ( INDEX `turntime` (`turntime`, `no`), INDEX `no_member` (`owner`), INDEX `npc` (`npc`), - INDEX `npcid` (`npcid`), INDEX `troop` (`troop`, `turntime`), - INDEX `level` (`nation`, `level`) + INDEX `level` (`nation`, `level`), + INDEX `name` (`name`) ) DEFAULT CHARSET=utf8mb4 ENGINE=MyISAM; diff --git a/src/sammo/Util.php b/src/sammo/Util.php index e7dfb861..71fd9384 100644 --- a/src/sammo/Util.php +++ b/src/sammo/Util.php @@ -309,16 +309,13 @@ class Util extends \utilphp\util if (is_string($key)) { return true; } - $jmp = $key - $idx - 1; + if(!$idx + 1 == $key){ + return false; + } $idx = $key; } - if ($jmp * 5 >= count($array)) { - //빈칸이 많으면 dictionary인걸로. - return true; - } else { - return false; - } + return true; } /** diff --git a/src/sammo/Validator.php b/src/sammo/Validator.php index 4d8377ac..24b9d1f4 100644 --- a/src/sammo/Validator.php +++ b/src/sammo/Validator.php @@ -33,4 +33,24 @@ class Validator extends \Valitron\Validator } + + /** + * Validate that a field is an integer array + * + * @param string $field + * @param mixed $value + * @return bool + */ + protected function validateIntegerArray($field, $value) + { + if(!is_array($value)){ + return false; + } + foreach($value as $subItem){ + if(!is_int($subItem)){ + return false; + } + } + return true; + } }