From f66d6557820511ed20f8b442265f99e588c9ccc6 Mon Sep 17 00:00:00 2001 From: hide_d Date: Mon, 15 Oct 2018 00:51:50 +0900 Subject: [PATCH] =?UTF-8?q?func=5Fnpc.php=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .phan/config.php | 1 - hwe/func.php | 1 - hwe/func_npc.php | 1464 ---------------------------------------------- 3 files changed, 1466 deletions(-) delete mode 100644 hwe/func_npc.php diff --git a/.phan/config.php b/.phan/config.php index 64650a86..3c9c65db 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -29,7 +29,6 @@ return [ 'hwe/func_legacy.php', 'hwe/func_map.php', 'hwe/func_message.php', - 'hwe/func_npc.php', 'hwe/func_process_chief.php', 'hwe/func_process_personnel.php', 'hwe/func_process_sabotage.php', diff --git a/hwe/func.php b/hwe/func.php index 0a0d064c..fbaa66a5 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -7,7 +7,6 @@ require_once 'func_process.php'; require_once 'func_process_sabotage.php'; require_once 'func_process_chief.php'; require_once 'func_process_personnel.php'; -require_once 'func_npc.php'; require_once 'func_tournament.php'; require_once 'func_auction.php'; require_once 'func_string.php'; diff --git a/hwe/func_npc.php b/hwe/func_npc.php deleted file mode 100644 index ae9c869b..00000000 --- a/hwe/func_npc.php +++ /dev/null @@ -1,1464 +0,0 @@ -queryFirstRow("SELECT trust,pop/pop2*100 as po,comm/comm2*100 as co,def/def2*100 as de,wall/wall2*100 as wa,secu/secu2*100 as se,agri/agri2*100 as ag from city where city=%i", $city); - - // 우선 선정 - if($city['trust'] < 95) { - return ['che_선정', null]; - } - - $prob = rand() % 100; - $command = 'che_물자조달'; - $arg = null; - - switch($genType) { - case 0: //무장 - case 2: //무내정장 - if($prob < 30) { - if($city['de'] < 99) { $command = 'che_수비강화'; } //수비 - elseif($city['po'] < 99) { $command = 'che_정착장려'; } //정장 - else { $command = 'che_물자조달'; } //조달 - } elseif($prob < 60) { - if($city['wa'] < 99) { $command = 'che_성벽강화'; } //성벽 - elseif($city['po'] < 99) { $command = 'che_정착장려'; } //정장 - else { $command = 'che_물자조달'; } //조달 - } elseif($prob < 90) { - if($city['se'] < 99) { $command = 'che_치안강화'; } //치안 - elseif($city['po'] < 99) { $command = 'che_정착장려'; } //정장 - else { $command = 'che_물자조달'; } //조달 - } else { - $command = 'che_인재탐색'; - } - break; - case 1: //지장 - case 3: //지내정장 - if($prob < 40) { - if($city['ag'] < 99) { $command = 'che_농지개간'; } //농업 - elseif($tech < GameConst::$maxTechLevel * 1000) { $command = 'che_기술연구'; } //기술 - elseif($city['po'] < 99) { $command = 'che_정착장려'; } //정장 - else { $command = 'che_물자조달'; } //조달 - } elseif($prob < 80) { - if($city['co'] < 99) { $command = 'che_상업투자'; } //상업 - elseif($tech < GameConst::$maxTechLevel * 1000) { $command = 'che_기술연구'; } //기술 - elseif($city['po'] < 99) { $command = 'che_정착장려'; } //정장 - else { $command = 'che_물자조달'; } //조달 - } elseif($prob < 90) { - if($tech < GameConst::$maxTechLevel * 1000) { $command = 'che_기술연구'; } //기술 - elseif($city['po'] < 99) { $command = 'che_정착장려'; } //정장 - else { $command = 'che_물자조달'; } //조달 - } else { - if($tech < GameConst::$maxTechLevel * 1000) { - if(Util::randBool()){ - $command = 'che_기술연구'; - } - else{ - $command = 'che_물자조달'; - } - } //기술, 조달 - else { $command = 'che_인재탐색'; } - } - break; - } - - // 장수수가 너무 많으면 탐색 확률 감소 - if($command == 'che_인재탐색') { - $genCount = $db->queryFirstField('SELECT count(no) FROM general'); - - $ratio = Util::round($genCount / 600 * 100); - - if(rand() % 100 < $ratio) { - $command = 'che_물자조달'; - } - } - - return [$command, $arg]; -} - -function SetCrew(General $generalObj, $genType):array{ - $db = DB::db(); - - $raw = $generalObj->getRaw(); - [$no, $nationID, $personal, $gold, $leader, $tech, $dex0, $dex10, $dex20, $dex30, $dex40] = [ - $raw['no'], $raw['nation'], $raw['personal'], $raw['gold'], $raw['leader'], $nation['tech'], - $raw['dex0'], $raw['dex10'], $raw['dex20'], $raw['dex30'], $raw['dex40'] - ]; - - - $cities = []; - $regions = []; - - foreach($db->queryAllLists('SELECT city, region FROM city WHERE nation = %i', $nationID) as [$cityID, $regionID]){ - $cities[$cityID] = true; - $regions[$regionID] = true; - } - - $gameStor = KVStorage::getStorage($db, 'game_env'); - [$startyear, $year] = $gameStor->getValuesAsArray(['startyear', 'year']); - $relYear = Util::valueFit($year-$startyear, 0); - - $type = 0; - switch($genType) { - case 0: //무장 - case 2: //무내정장 - $dex0 = $dex0 + rand()%1000; - $dex10 = $dex10 + rand()%1000; - $dex20 = $dex20 + rand()%1000; - $sel = 0; - // 보궁기 선택 - if($dex0 > $dex10) { - if($dex0 > $dex20) { - $sel = 0; - } else { - $sel = 2; - } - } else { - if($dex10 > $dex20) { - $sel = 1; - } else { - $sel = 2; - } - } - - - - $types = []; - switch($sel) { - case 0: - foreach(GameUnitConst::byType(GameUnitConst::T_FOOTMAN) as $crewtype){ - if($crewtype->isValid($cities, $regions, $relYear, $tech)){ - $types[] = $crewtype->id; - } - } - break; - case 1: - foreach(GameUnitConst::byType(GameUnitConst::T_ARCHER) as $crewtype){ - if($crewtype->isValid($cities, $regions, $relYear, $tech)){ - $types[] = $crewtype->id; - } - } - break; - case 2: - foreach(GameUnitConst::byType(GameUnitConst::T_CAVALRY) as $crewtype){ - if($crewtype->isValid($cities, $regions, $relYear, $tech)){ - $types[] = $crewtype->id; - } - } - break; - } - break; - case 1: //지장 - case 3: //지내정장 - foreach(GameUnitConst::byType(GameUnitConst::T_WIZARD) as $crewtype){ - if($crewtype->isValid($cities, $regions, $relYear, $tech)){ - $types[] = $crewtype->id; - } - } - break; - } - - if($types){ - $type = Util::choiceRandom($types); - } - else{ - $type = GameUnitConst::DEFAULT_CREWTYPE; - } - - - - $gold -= 200; // 사기비용 - - $cost = getCost($type) * getTechCost($tech); - $cost = CharCost($cost, $personal); - - $crew = intdiv($gold, $cost); - if($leader < $crew) { $crew = $leader; } - $arg = [ - 'crewType'=>$type, - 'amountCrew'=>$crew - ]; - return ['che_징병', $arg]; -} - -function processAINationTurn(General $generalObj, $command, $arg):array{ - $nation = $db->queryFirstRow( - 'SELECT nation,level,tech,gold,rice,rate,type,color,name,war FROM nation WHERE nation = %i', - $generalObj->getNationID() - )??[ - 'nation'=>0, - 'level'=>0, - 'tech'=>0, - 'gold'=>0, - 'rice'=>0, - 'type'=>GameConst::$neutralNationType, - 'color'=>'#000000', - 'name'=>'재야', - ]; -} - -function processAI(General $generalObj, $command, $arg):array{ - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - $connect=$db->get(); - - $admin = $gameStor->getValues(['startyear','year','month','turnterm','scenario','gold_rate','rice_rate']); - // 초반 여부 - if($admin['startyear']+2 > $admin['year'] || ($admin['startyear']+2 == $admin['year'] && $admin['month'] < 5)) { - $isStart = 1; - } else { - $isStart = 0; - } - - $general = $generalObj->getRaw(); - $generalID = $generalObj->getID(); - - if($general['npc'] == 5){ - if($general['nation'] == 0 && $general['killturn'] > 1){ - $command = 'che_휴식'; //휴식 - $arg = []; - $generalObj->setVar('killturn', 1); - } - else{ - $command = 'che_집합'; //집합 - $arg = []; - $generalObj->setVar('killturn', rand(70,75)); - //NOTE: 부대 편성에 보여야 하므로 이것만 DB에 직접 접근함. - $db->update('general_turn', [ - 'action'=>'che_집합', - 'arg'=>'{}' - ], 'general_ID=%i AND turn_idx < 6', $generalID); - } - - return [$command, $arg]; - } - - // 입력된 턴이 있으면 그것 실행 - if($command && $command != '휴식') { - return [$command, $arg]; - } - - $command = 'che_물자조달'; - $arg = []; - - $city = $generalObj->getRawCity(); - $nation = $generalObj->getStaticNation(); - - - $coreCommand = array(); - if($general['level'] >= 5) { - $query = "select l{$general['level']}turn0 from nation where nation='{$general['nation']}'"; - $result = MYDB_query($query, $connect) or Error("processAI03 ".MYDB_error($connect),""); - $coreCommand = MYDB_fetch_array($result); - } - - $cityCount = $db->queryFirstField('SELECT count(city) FROM city WHERE nation=%i AND supply=1 AND front>0', $general['nation']); - // 공격가능도시 있으면 1 - $attackable = $cityCount > 0; - - $dipState = 0; - $query = "select no from diplomacy where me='{$general['nation']}' and state=1 and term>8"; - $result = MYDB_query($query, $connect) or Error("processAI04 ".MYDB_error($connect),""); - $dipCount = MYDB_num_rows($result); - // 선포중이면 1상태 - if($dipCount > 0) { $dipState = 1; } - - $query = "select no from diplomacy where me='{$general['nation']}' and state=1 and term<=8"; - $result = MYDB_query($query, $connect) or Error("processAI04 ".MYDB_error($connect),""); - $dipCount = MYDB_num_rows($result); - // 전쟁준비 선포중이면 2상태 - if($dipCount > 0) { $dipState = 2; } - - $query = "select no from diplomacy where me='{$general['nation']}' and state=1 and term<=5"; - $result = MYDB_query($query, $connect) or Error("processAI04 ".MYDB_error($connect),""); - $dipCount = MYDB_num_rows($result); - // 교전 직전이면 3상태 - if($dipCount > 0) { $dipState = 3; } - - $query = "select no from diplomacy where me='{$general['nation']}' and state=0"; - $result = MYDB_query($query, $connect) or Error("processAI04 ".MYDB_error($connect),""); - $dipCount = MYDB_num_rows($result); - // 교전중이면 4상태 - if($dipCount > 0) { $dipState = 4; } - - - - $tech = getTechCost($nation['tech']); - $resrc = $tech * 700;//XXX: 왜 700이지? - - if($general['atmos'] >= 90 && $general['train'] >= 90) { - if($general['mode'] == 0) { - $query = "update general set mode=1 where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),""); - } - } else { - if($general['mode'] == 1) { - $query = "update general set mode=0 where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),""); - } - } - - //운영자메시지 출력 하루 6번..? - //특별 메세지 있는 경우 출력 하루 4번 - $term = $admin['turnterm']; - if($general['npcmsg'] && Util::randBool($term / (6*60))) { - $src = new MessageTarget( - $generalID, - $general['name'], - $general['nation'], - $nation['name'], - $nation['color'], - GetImageURL($general['imgsvr'], $general['picture']) - ); - $msg = new Message( - Message::MSGTYPE_PUBLIC, - $src, - $src, - $general['npcmsg'], - new \DateTime(), - new \DateTime('9999-12-31'), - [] - ); - $msg->send(); - } - - //재야인경우 - if($general['npc'] == 9 && $general['level'] == 0) { - // 오랑캐는 바로 임관 - - $rulerNation = $db->queryFirstField('SELECT nation FROM general WHERE `level`=12 AND npc=9 and nation not in %li ORDER BY RAND() limit 1', Json::decode($general['nations'])); - - if($ruler) { - $command = EncodeCommand(0, 0, $rulerNation, 25); //임관 - } else { - $command = 'che_견문'; //견문 - } - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI07 ".MYDB_error($connect),""); - return []; - - } elseif($general['npc'] != 9 && $general['level'] == 0) { - switch(Util::choiceRandomUsingWeight([11.4, 40, 20, 28.6])) { - //임관 10% - case 0: - - $available = true; - - if($admin['startyear']+3 > $admin['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['affinity'] == 999 || !$available){ - $command = 'che_견문'; //견문 - } - else{ - //랜임 커맨드 입력. - $command = EncodeCommand(0, 0, 99, 25); //임관 - } - break; - case 1: //거병이나 견문 40% - // 초반이면서 능력이 좋은놈 위주로 1.4%확률로 거병 - $prop = Util::randF() * (GameConst::$defaultStatNPCMax + GameConst::$chiefStatMin) / 2; - $ratio = ($general['leader'] + $general['power'] + $general['intel']) / 3; - if($admin['startyear']+2 > $admin['year'] && $prop < $ratio && Util::randBool(0.014) && $general['makelimit'] == 0) { - //거병 - $command = 'che_거병'; - } else { - //견문 - $command = 'che_견문'; - } - break; - case 2: //이동 20% - $paths = explode('|', $city['path']); - $command = EncodeCommand(0, 0, $paths[rand()%count($paths)], 21); - break; - default: - $command = 'che_견문'; - break; - } - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI07 ".MYDB_error($connect),""); - return []; - } - - $rulerCommand = 0; - //군주가 할일 - if($general['level'] == 12) { - //오랑캐인데 공격 못하면 바로 방랑/해산 - if($general['npc'] == 9 && $dipState == 0 && !$attackable) { - //방랑군이냐 아니냐 - if($nation['level'] == 0) { - // 해산 - $command = 'che_해산'; - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI09 ".MYDB_error($connect),""); - return; - } else { - // 방랑 - $command = 'che_방랑'; - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI09 ".MYDB_error($connect),""); - return; - } - } - //분기마다 - if($admin['month'] == 1 || $admin['month'] == 4 || $admin['month'] == 7 || $admin['month'] == 10) { - //관직임명 - Promotion($general['nation'], $nation['level']); - } elseif($admin['month'] == 12) { - //세율 - $nation['rate'] = TaxRate($general['nation']); - //지급율 - GoldBillRate($nation['nation'], $nation['rate'], $admin['gold_rate'], $nation['type'], $nation['gold']); - } elseif($admin['month'] == 6) { - //세율 - $nation['rate'] = TaxRate($general['nation']); - //지급율 - RiceBillRate($nation['nation'], $nation['rate'], $admin['rice_rate'], $nation['type'], $nation['rice']); - } - - //방랑군이냐 아니냐 - if($nation['level'] == 0) { - if($admin['startyear']+2 <= $admin['year']) { - // 해산 - $command = 'che_해산'; - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI09 ".MYDB_error($connect),""); - return; - } elseif($city['nation'] == 0 && ($city['level'] == 5 || $city['level'] == 6)) { - $type = rand()%9 + 1; - $colors = GetNationColors(); - $color = rand() % count($colors); - $command = EncodeCommand(0, $type, $color, 46); - $nationName = "㉿".mb_substr($general['name'], 1); - //건국 - $query = "update general set turn0='$command',makenation='$nationName' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI08 ".MYDB_error($connect),""); - return; - } elseif(rand()%4 > 0) { - //이동 - $paths = explode('|', $city['path']); - $command = EncodeCommand(0, 0, $paths[rand()%count($paths)], 21); - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI09 ".MYDB_error($connect),""); - return; - } else { - //조달 - $command = 'che_물자조달'; - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI09 ".MYDB_error($connect),""); - return; - } - //NOTE: 여기까지 구현함 - } else { - //외교 평시에 선포 - - do{ - if($dipState != 0){ - break; - } - if($attackable){ - break; - } - - SetNationFront($nation['nation']); - - $frontCount = $db->queryFirstField('SELECT count(city) FROM city WHERE nation=%i AND front>0', $general['nation']); - if($frontCount > 0){ - break; - } - - $devRate = $db->queryFirstField('SELECT (sum(pop/10)+sum(agri)+sum(comm)+sum(secu)+sum(def)+sum(wall))/(sum(pop2/10)+sum(agri2)+sum(comm2)+sum(secu2)+sum(def2)+sum(wall2)) from city where nation=%i', $general['nation']); - if($devRate < 0.8){ - break; - } - - $nations = []; - foreach ($db->queryAllLists('SELECT nation, power FROM nation WHERE level>0') as [$youNationID, $youNationPower]) { - if(!isNeighbor($general['nation'], $youNationID)){ - continue; - } - $nations[$youNationID] = 1/sqrt($youNationPower+1); - } - if(!$nations){ - break; - } - $youNationID = Util::choiceRandomUsingWeight($nations); - $command = EncodeCommand(0, 0, $youNationID, 62); - $db->update('nation', [ - 'l12turn0'=>$command - ], 'nation=%i', $general['nation']); - $rulerCommand = 1; - }while(false); - } - } - - // 입력된 턴이 있으면 - if(!empty($coreCommand) && ($coreCommand["l{$general['level']}turn0"] != 'che_휴식')) { - $rulerCommand = 1; - } - - //방랑군 아니고, 입력된 턴이 없을때 수뇌부가 할일 - if($nation['level'] != 0 && $general['level'] >= 5 && $rulerCommand == 0) { - $command = NPCStaffWork($general, $nation, $dipState); - if($command){ - $db->update('nation', [ - "l{$general['level']}turn0"=>$command - ], 'nation=%i', $general['nation']); - } - } - - $command = '<내정>'; - //일반 할일 - if($general['killturn'] < 5) { - if($general['gold'] + $general['rice'] == 0) { - $command = 'che_물자조달'; //조달 - } elseif($general['gold'] > $general['rice']) { - $command = EncodeCommand(0, 1, 100, 44); //헌납 - } else { - $command = EncodeCommand(0, 2, 100, 44); //헌납 - } - } elseif($general['injury'] > 10) { - // 부상 2달 이상이면 요양 - $command = 'che_요양'; //요양 - } elseif($nation['level'] == 0) { - //방랑군일때 - if($admin['startyear']+3 <= $admin['year']) { - $command = 'che_하야'; //하야 - } else { - switch(rand()%5) { - case 0: - $command = 'che_견문'; break; //견문 20% - case 1: case 2: case 3: case 4: - $command = 'che_물자조달'; break; //조달 80% - } - } - } else { - //국가일때 - //아국땅 아니면 귀환 - if($general['nation'] != $city['nation'] || $city['supply'] == 0) { - $command = 'che_귀환'; //귀환 - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI23 ".MYDB_error($connect),""); - return; - } - - if($general['leader'] < 40){ - //무지장인데 - - if( - (($nation['rice'] - GameConst::$baserice) * 3 <= $general['rice'] && $general['rice'] >= $resrc + 2100) || - ($general['rice'] >= 11000) - ){ - //쌀을 많이 들고 있다면 - $amount = $general['rice'] * 0.9; - $amount = intdiv(Util::valueFit($amount, $resrc + 1000, 10000), 100); - - $command = EncodeCommand(0, 2, $amount, 44); //헌납 - $db->update('general', [ - 'turn0'=>$command - ], 'no=%i',$generalID); - return; - } - - if( - (($nation['gold'] - GameConst::$basegold) * 3 <= $general['gold'] && $general['gold'] >= $resrc + 2100) || - ($general['gold'] >= 12000) - ){ - //금을 많이 들고 있다면 - $amount = $general['gold'] * 0.9; - $amount = intdiv(Util::valueFit($amount, $resrc + 1000, 10000), 100); - - $command = EncodeCommand(0, 1, $amount, 44); //헌납 - $db->update('general', [ - 'turn0'=>$command - ], 'no=%i',$generalID); - return; - } - } - - //국가 병량이 없을때 바로 헌납 - if($nation['rice'] < 2000 && $general['rice'] > 200) { - $amount = intdiv($general['rice'] - 200, 100) + 1; - if($amount > 20) { $amount = 20; } - $command = EncodeCommand(0, 2, $amount, 44); //헌납 - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI23 ".MYDB_error($connect),""); - return; - } - -// R -// ┃ ┃ 공격/내정 -// 500┃쌀┣━━━━┓ -// ┃팜┃ ┃ -// 100┣━┫ 내정 ┣━━━ -// ┃조┃ ┃쌀삼 -// 0┗━┻━━━━┻━━━> G -// 100 500 - - $target = array(); - // 평시거나 초반아니면서 공격가능 없으면서 병사 있으면 해제(25%) - if($dipState == 0 && $isStart == 0 && !$attackable && $general['crew'] > 0 && rand()% 100 < 25) { - $command = 'che_소집해제'; //소집해제 - } elseif($dipState <= 1 || $isStart == 1) { - //평시이거나 선포있어도 초반이면 - if($general['gold'] + $general['rice'] < 200) { $command = 'che_물자조달'; } //금쌀없으면 조달9 - elseif($general['rice'] > 100 && $city['trust'] < 95) { $command = 'che_주민선정'; } //우선 선정 - elseif($general['gold'] < 100) { //금없으면 쌀팜 - $amount = intdiv(($general['rice'] - $general['gold'])/2, 100); // 100단위 - $command = EncodeCommand(0, 1, $amount, 49); //팜 - } elseif($general['gold'] < 500 && $general['rice'] < 500) { $command = '<내정>'; } //금쌀되면 내정 - elseif($general['rice'] < 100) { //쌀없으면 쌀삼 - $amount = intdiv(($general['gold'] - $general['rice'])/2, 100); // 100단위 - $command = EncodeCommand(0, 2, $amount, 49); //삼 - } elseif($genType >= 2) { $command = '<내정>'; } //내정장일때 내정 - else { - //현도시가 전방이면 공격 가능성 체크 - if($city['front'] > 0) { - //주변도시 체크 - $paths = explode('|', $city['path']); - for($i=0; $i < count($paths); $i++) { - $query = "select city,nation from city where city='$paths[$i]'"; - $result = MYDB_query($query, $connect) or Error("processAI20 ".MYDB_error($connect),""); - $targetCity = MYDB_fetch_array($result); - //공백지이면 타겟에 포함 - if($targetCity['nation'] == 0) { $target[] = $targetCity['city']; } - } - if(count($target) == 0 || $isStart == 1 || $nation['war'] == 1) { $command = '<내정>'; } //공격 가능도시가 없으면 내정 - else { $command = EncodeCommand(0, 0, $target[rand()%count($target)], 16); } //있으면 공격 - } else { - //전방 아니면 내정 - $command = '<내정>'; - } - - if($command == '<내정>') { // 공격아닌 경우 - $query = "select city,(pop/10+agri+comm+secu+def+wall)/(pop2/10+agri2+comm2+secu2+def2+wall2)*100 as dev from city where city='{$general['city']}'"; - $result = MYDB_query($query, $connect) or Error("processAI19 ".MYDB_error($connect),""); - $selCity = MYDB_fetch_array($result); - - $sel = rand() % 10; - if($selCity['dev'] > 95) { $sel = 9; } - elseif($selCity['dev'] < 70) { $sel = 0; } - switch($sel) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 그대로 내정 80 % - $command = '<내정>'; - break; - case 8: case 9: // 저개발 도시로 워프 20% - //도시 선택, 30% 확률로 군사 있는 곳으로 워프 - if(rand()%100 < 30) { - $query = "select city,(pop/10+agri+comm+secu+def+wall)/(pop2/10+agri2+comm2+secu2+def2+wall2)*100 as dev from city where nation='{$general['nation']}' and supply='1' order by gen2 desc,dev limit 0,1"; - } else { - $query = "select city,(pop/10+agri+comm+secu+def+wall)/(pop2/10+agri2+comm2+secu2+def2+wall2)*100 as dev from city where nation='{$general['nation']}' and supply='1' order by dev limit 0,1"; - } - $result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),""); - $selCity = MYDB_fetch_array($result); - //이미 그 도시이거나, 그 도시도 고개발이면 내정 - if($selCity['city'] == $general['city'] || $selCity['dev'] > 95) { - $command = '<내정>'; - } else { - //워프 - $query = "update general set city='{$selCity['city']}' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI18 ".MYDB_error($connect),""); - - $command = 'che_요양'; //요양 - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI23 ".MYDB_error($connect),""); - return; - } - break; - } - -// ┃ ┃ -// ┃ 쌀팜 ┃ 공격 -// ┃ ┃ -// 700t┣━━━━╋━━━━━━━━━ -// ┃내조 ↗┃ -// ┃ ↗ ┃ -// ┣━┓내조┃ 쌀삼 -// ┃**┃ ┃ -// 0 ┗━┻━━━━━━━> G -// 700t - - } else { // 공격인 경우 - if($general['crew'] < 1000 && $general['gold'] >= $resrc && $general['rice'] >= $resrc) { //자원되고, 병사없을때 - if($city['pop'] > 40000) { $command = '<징병>'; } - else { $command = '<내정>'; } - } elseif($general['rice'] < $resrc && $general['rice'] <= $general['gold']) { - //금이 더 많으면 매매 - $amount = intdiv(($general['gold'] - $general['rice']) / 2, 100); // 100단위 - if($amount > 0) { $command = EncodeCommand(0, 2, $amount, 49); }//삼 - else { $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); } // 내정, 조달 - } elseif($general['gold'] < $resrc && $general['rice'] > $general['gold']) { - //쌀이 더 많으면 매매 - $amount = intdiv(($general['rice'] - $general['gold']) / 2, 100); // 100단위 - if($amount > 0) { $command = EncodeCommand(0, 1, $amount, 49); }//팜 - else { $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); } // 내정, 조달 - //자원, 병사 모두 충족 - } elseif($general['crew'] >= 1000 && $general['train'] < 90) { - $command = 'che_훈련'; //훈련 - } elseif($general['crew'] >= 1000 && $general['atmos'] < 90) { - $command = 'che_사기진작'; //사기진작 - } else { - //공격 - //$command = $target[rand()%count($target)] * 100 + 16; //있으면 공격 - } - } - } - } else { -// R -// ┃ ┃ -// ┃쌀┃ -// ┃팜┃ 공격 -//1000t┣━╋━━━━━ -// ┃조┃ 쌀삼 -// 0┗━┻━━━━━> G -// 1000t - - //전시일때 - if($general['gold'] + $general['rice'] < $resrc*2) { $command = 'che_물자조달'; } //금쌀없으면 조달 - elseif($general['rice'] > $resrc && $city['rate'] < 95 && $city['front'] == 0) { $command = 'che_주민선정'; } // 우선 선정 - elseif($general['rice'] > $resrc && $city['rate'] < 50 && $city['front'] > 0) { $command = 'che_주민선정'; } // 우선 선정 - elseif($general['gold'] < $resrc || ($general['gold'] < $resrc *2 && $general['rice'] > $resrc * 6)) { // 금없으면 쌀팜 - $amount = intdiv(($general['rice'] - $general['gold'])/2, 100); // 100단위 - if($amount > 0) { $command = EncodeCommand(0, 1, $amount, 49); }// 팜 - else { $command = 'che_물자조달'; } // 조달 - } elseif($general['rice'] < $resrc || ($general['rice'] < $resrc *2 && $general['gold'] > $resrc * 6)) { // 쌀없으면 쌀삼 - $amount = intdiv(($general['gold'] - $general['rice'])/2, 100); // 100단위 - if($amount > 0) { $command = EncodeCommand(0, 2, $amount, 49); }// 팜 - else { $command = 'che_물자조달'; } // 조달 - } elseif($genType >= 2) { $command = '<내정>'; } //내정장일때 내정 - elseif($general['crew'] < 1000 && $general['gold'] >= $resrc && $general['rice'] >= $resrc) { - $query = "select no from general where nation='{$general['nation']}'"; - $result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),""); - $genCount = MYDB_num_rows($result); - - $query = "select no from general where nation='{$general['nation']}' and city='{$general['city']}'"; - $result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),""); - $genCount2 = MYDB_num_rows($result); - - $query = "select sum(pop) as sum from city where nation='{$general['nation']}' and supply='1'"; - $result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),""); - $sumCity = MYDB_fetch_array($result); - // 현도시 인구 비율 - $ratio = Util::round($city['pop'] / $sumCity['sum'] * 100); - // 현도시 장수 비율 - $ratio2 = Util::round($genCount2 / $genCount * 100); - $ratio3 = rand() % 100; - // 전체 인구 대비 확률로 현지에서 징병 - if($city['pop'] > 40000 && 100 + $ratio - $ratio2 > $ratio3) { - $command = '<징병>'; //인구 되면 징병 - } else { - // 인구 안되면 4만 이상인 도시로 워프 - $query = "select city from city where nation='{$general['nation']}' and pop>40000 and supply='1' order by rand() limit 0,1"; - $result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),""); - $cityCount = MYDB_num_rows($result); - if($cityCount > 0) { - $selCity = MYDB_fetch_array($result); - //워프 - $query = "update general set city='{$selCity['city']}' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI18 ".MYDB_error($connect),""); - - $command = 'che_요양'; //요양 - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI23 ".MYDB_error($connect),""); - return; - } else { - $command = 'che_정착장려'; //인구 안되면 정장 - } - } - } elseif($general['crew'] >= 1000 && $general['train'] < 90) { - if($general['atmos'] >= 90 && $general['train'] >= 60 && $general['mode'] == 0) { - $query = "update general set mode=1 where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),""); - } - $command = 'che_훈련'; //훈련 - } elseif($general['crew'] >= 1000 && $general['atmos'] < 90) { - if($general['atmos'] >= 60 && $general['train'] >= 90 && $general['mode'] == 0) { - $query = "update general set mode=1 where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),""); - } - $command = 'che_사기진작'; //사기진작 - } elseif($dipState <= 3) { - $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); // 준비는 됐으나 아직 선포중이면 내정, 조달 - } else { - //공격 & 내정 - $paths = explode('|', $city['path']); - for($i=0; $i < count($paths); $i++) { - $query = "select city,nation from city where city='$paths[$i]'"; - $result = MYDB_query($query, $connect) or Error("processAI21 ".MYDB_error($connect),""); - $targetCity = MYDB_fetch_array($result); - //소유국이 있는 경우 - if($targetCity['nation'] != 0 && $targetCity['nation'] != $general['nation']) { - $query = "select state from diplomacy where me='{$general['nation']}' and you='{$targetCity['nation']}'"; - $dipResult = MYDB_query($query, $connect) or Error("processAI22 ".MYDB_error($connect),""); - $dip = MYDB_fetch_array($dipResult); - //전쟁중인 국가이면 타겟에 포함 - if($dip['state'] == 0) $target[] = $targetCity['city']; - } - } - if(count($target) == 0) { - //전방 도시 선택, 30% 확률로 태수 있는 전방으로 워프 - if(rand()%100 < 30) { - $query = "select city from city where nation='{$general['nation']}' and supply='1' and front>0 order by gen1 desc,rand() limit 0,1"; - } else { - $query = "select city from city where nation='{$general['nation']}' and supply='1' and front>0 order by rand() limit 0,1"; - } - $result = MYDB_query($query, $connect) or Error("processAI10 ".MYDB_error($connect),""); - $cityCount = MYDB_num_rows($result); - if($cityCount == 0) { - //도시 수, 랜덤(상위 20%) 선택, 저개발 도시 선택 - $query = "select city from city where nation='{$general['nation']}' and supply='1'"; - $result = MYDB_query($query, $connect) or Error("processAI10 ".MYDB_error($connect),""); - $cityCount = MYDB_num_rows($result); - $citySelect = rand() % (Util::round($cityCount/5) + 1); - - $query = "select city,(def+wall)/(def2+wall2) as dev from city where nation='{$general['nation']}' and supply='1' order by dev limit {$citySelect},1"; - $result = MYDB_query($query, $connect) or Error("processAI10 ".MYDB_error($connect),""); - $selCity = MYDB_fetch_array($result); - } else { - $selCity = MYDB_fetch_array($result); - } - - if($general['city'] != $selCity['city']) { - //워프 - $query = "update general set city='{$selCity['city']}' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI18 ".MYDB_error($connect),""); - - $command = 'che_요양'; //요양 - $query = "update general set turn0='$command' where no='{$generalID}'"; - MYDB_query($query, $connect) or Error("processAI23 ".MYDB_error($connect),""); - return; - } else { - $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); //공격 가능도시가 없고 워프도 안되면 내정, 조달 - } - } elseif($nation['war'] == 1) { - //전금이면 내정, 조달 - $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); //내정, 조달 - } else { $command = EncodeCommand(0, 0, $target[rand()%count($target)], 16); } //있으면 공격 - } - } - } - - switch($command) { - case '<내정>': //내정 - return SetDevelop($generalObj, $genType); - case '<징병>': //징병 - return SetCrew($generalObj, $genType); - default: - return [$command, $arg]; - } -} - - -function NPCStaffWork($general, $nation, $dipState){ - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - $connect=$db->get(); - - $generalID = $general['no']; - - $admin = $gameStor->getValues(['startyear','year','month','turnterm','scenario','gold_rate','rice_rate', 'develcost']); - - $nationCities = []; - $frontCitiesID = []; - $frontImportantCitiesID = []; - $supplyCitiesID = []; - $backupCitiesID = []; - - $tech = getTechCost($nation['tech']); - - foreach ($db->query('SELECT * FROM city WHERE nation = %i', $general['nation']) as $nationCity) { - $nationCity['generals'] = []; - $cityID = $nationCity['city']; - $dev = - ($nationCity['agri'] + $nationCity['comm'] + $nationCity['secu'] + $nationCity['def'] + $nationCity['wall'])/ - ($nationCity['agri'] + $nationCity['comm'] + $nationCity['secu'] + $nationCity['def'] + $nationCity['wall']); - $dev += $nationCity['pop'] / $nationCity['pop2']; - $dev /= 50; - - $nationCity['dev'] = $dev; - - $nationCities[$cityID] = $nationCity; - - if($nationCity['supply']){ - $supplyCitiesID[] = $cityID; - if($nationCity['front']){ - $frontCitiesID[] = $cityID; - if($nationCity['gen1']){ - $frontImportantCitiesID[] = $cityID; - } - } - else{ - $backupCitiesID[] = $cityID; - } - } - } - Util::shuffle_assoc($nationCities); - shuffle($frontCitiesID); - shuffle($supplyCitiesID); - - $nationGenerals = []; - $lostGeneralsID = []; - - $userGeneralsID = []; - $npcWarGeneralsID = []; - $npcCivilGeneralsID = []; - - - $commandList = []; - - foreach($db->query('SELECT `no`, nation, city, npc, `gold`, `rice`, leader, `power`, intel, killturn, crew, train, atmos, `level`, troop FROM general WHERE nation = %i', $general['nation']) as $nationGeneral) { - $cityID = $nationGeneral['city']; - $generalID = $nationGeneral['no']; - - if($generalID == $generalID){ - continue; - } - - if(key_exists($cityID, $nationCities)){ - $nationCities[$cityID]['generals'][] = $generalID; - if(!$nationCities[$cityID]['supply']){ - $lostGeneralsID[] = $generalID; - } - } - else{ - $lostGeneralsID[] = $generalID; - } - - if($nationGeneral['npc']<2 && $nationGeneral['killturn'] >= 5){ - $userGeneralsID[] = $generalID; - } - else if($nationGeneral['leader']>=40 && $nationGeneral['killturn'] >= 5){ - $npcWarGeneralsID[] = $generalID; - } - else{ - //삭턴이 몇 안남은 장수는 '내정장 npc'로 처리 - $npcCivilGeneralsID[] = $generalID; - } - - $nationGenerals[$generalID] = $nationGeneral; - } - Util::shuffle_assoc($nationGenerals); - shuffle($lostGeneralsID); - - uasort($nationCities, function($lhs, $rhs){ - //키 순서를 지키지 않지만, 원래부터 random order를 목표로 하므로 크게 신경쓰지 않는다. - return count($lhs['generals']) - count($rhs['generals']); - }); - - - //타 도시에 있는 '유저장' 발령 - foreach($lostGeneralsID as $lostGeneralID){ - $lostGeneral = $nationGenerals[$lostGeneralID]; - if($lostGeneral['npc'] < 2){ - if($dipState >= 3 && $frontCitiesID){ - $selCityID = Util::choiceRandom($frontCitiesID); - } - else{ - $selCityID = Util::choiceRandom($supplyCitiesID); - } - $commandList[EncodeCommand(0, $lostGeneralID, $selCityID, 27)] = 200; - } - } - - - $resBaseType = [['gold', 1], ['rice', 2]]; - [$resName, $resType] = Util::choiceRandom($resBaseType); - - usort($userGeneralsID, function($lhs, $rhs) use ($nationGenerals, $resName){ - return $nationGenerals[$lhs][$resName] - $nationGenerals[$rhs][$resName]; - }); - - usort($npcWarGeneralsID, function($lhs, $rhs) use ($nationGenerals, $resName){ - return $nationGenerals[$lhs][$resName] - $nationGenerals[$rhs][$resName]; - }); - - usort($npcCivilGeneralsID, function($lhs, $rhs) use ($nationGenerals, $resName){ - return $nationGenerals[$lhs][$resName] - $nationGenerals[$rhs][$resName]; - }); - - $avgUserRes = 0; - foreach ($userGeneralsID as $id){ - $avgUserRes += $nationGenerals[$id][$resName]; - } - $avgUserRes /= max(1, count($userGeneralsID)); - - $avgNpcWarRes = 0; - foreach ($npcWarGeneralsID as $id){ - $avgNpcWarRes += $nationGenerals[$id][$resName]; - } - $avgNpcWarRes /= max(1, count($npcWarGeneralsID)); - - $avgNpcCivilRes = 0; - foreach ($npcCivilGeneralsID as $id){ - $avgNpcCivilRes += $nationGenerals[$id][$resName]; - } - $avgNpcCivilRes /= max(1, count($npcCivilGeneralsID)); - - - - //금쌀이 부족한 '유저장' 먼저 포상 - while ($nation[$resName] > ($resName=='gold'?1:2)*3000 && $userGeneralsID) { - $isWarUser = null; - - foreach($userGeneralsID as $userGeneralID){ - $compUser = $nationGenerals[$userGeneralID]; - if($compUser['leader'] >= 50){ - $isWarUser = true; - break; - } - if(Util::randBool(0.2)){ - $isWarUser = false; - break; - } - } - - if($isWarUser === null){ - break; - } - - $compRes = $compUser[$resName]; - - $work = false; - if(!$isWarUser){ - $work = false; - } else if ($compRes < $avgNpcWarRes*3) { - $work = true; - } elseif ($compRes < $avgNpcCivilRes * 4) { - $work = true; - } - - if((($isWarUser || $resName == 'gold') && $compUser[$resName] < 21000) || ($compUser[$resName] < 5000)){ - if($work){ - $amount = min(100, intdiv(($nation[$resName]-($resName=='rice'?(GameConst::$baserice):(GameConst::$basegold))), 3000)*10 + 10); - $commandList[EncodeCommand($resType, $userGeneralsID[0], $amount, 23)] = 10; // 금,쌀 1000단위 포상 - } - else{ - $amount = min(100, intdiv(($nation[$resName]-($resName=='rice'?(GameConst::$baserice):(GameConst::$basegold))), 5000)*10 + 10); - $commandList[EncodeCommand($resType, $userGeneralsID[0], $amount, 23)] = 1; // 금,쌀 1000단위 포상 - } - - } - break; - } - - $minRes = $admin['develcost'] * 24 * $tech; - - if($nation[$resName] < ($resName=='gold'?1:2)*3000) { // 몰수 - // 몰수 대상 - $compUser = $userGeneralsID?$nationGenerals[end($userGeneralsID)]:null; - $compNpcWar = $npcWarGeneralsID?$nationGenerals[end($npcWarGeneralsID)]:null; - $compNpcCivil = $npcCivilGeneralsID?$nationGenerals[end($npcCivilGeneralsID)]:null; - - $compUserRes = $compUser[$resName]??0; - $compNpcWarRes = $compNpcWar[$resName]*5??0; - $compNpcCivilRes = $compNpcCivil[$resName]*10??0; - - [$compRes, $compGenID] = max( - [$compNpcCivilRes, $compNpcCivil['no']??null], - [$compNpcWarRes, $compNpcWar['no']??null], - [$compUserRes, $compUser['no']??null] - ); - - if($compGenID){ - $targetGeneral = $nationGenerals[$compGenID]; - if($compGenID === ($compNpcCivil['no']??null)){ - $amount = intdiv($targetGeneral[$resName] - $minRes * 3, 100); - } - else{ - $amount = min(100, intdiv($targetGeneral[$resName], 5000)*10 + 10); - } - - if($amount > 0){ - $commandList[EncodeCommand($resType, $compGenID, $amount, 24)] = 3; - } - - } - } else{ // 포상 - $compNpcWar = $npcWarGeneralsID?$nationGenerals[$npcWarGeneralsID[0]]:null; - $compNpcCivil = null; - foreach($npcCivilGeneralsID??[] as $npcCivilID){ - $npcCivil = $nationGenerals[$npcCivilID]; - if($npcCivil['npc'] == 5){ - continue; - } - $compNpcCivil = $npcCivil; - break; - } - - if($compNpcWar && $compNpcWar[$resName] < 21000){ - $amount = min(100, intdiv(($nation[$resName]-($resName=='rice'?(GameConst::$baserice):(GameConst::$basegold))), 5000)*10 + 10); - $commandList[EncodeCommand($resType, $compNpcWar['no'], $amount, 23)] = 3; - } - if($compNpcCivil && $compNpcCivil[$resName] < $minRes){ - $amount = intdiv($minRes+99, 100); - $commandList[EncodeCommand($resType, $compNpcCivil['no'], $amount, 23)] = 2; - } - } - - //고립 도시 장수 발령 - foreach($lostGeneralsID as $lostGeneralID){ - $lostGeneral = $nationGenerals[$lostGeneralID]; - if($lostGeneral['npc']<2){ - //고립 유저 장수는 이미 세팅했음 - continue; - } - if($dipState >= 3 && $frontCitiesID){ - $selCityID = Util::choiceRandom($frontCitiesID); - } - else{ - $selCityID = Util::choiceRandom($supplyCitiesID); - } - //고립된 장수가 많을 수록 발령 확률 증가 - $commandList[EncodeCommand(0, $lostGeneralID, $selCityID, 27)] = sqrt(count($lostGeneralsID)) * 10; - } - - // 평시엔 균등 발령만 - if($dipState <= 1 && count($supplyCitiesID) > 1) { - $targetCity = null; - $minCity = null; - $maxCity = null; - $maxDevCity = null; - foreach($nationCities as $nationCity){ - if($nationCity['dev']>=95){ - continue; - } - if($nationCity['supply']){ - $minCity = $nationCity; - break; - } - - } - - //reverse_order T_T - $maxCity = end($nationCities); - if(!$minCity){ - $minCity = $maxCity; - } - while($maxCity['city'] !== $minCity['city']){ - if($nationCity['supply']){ - break; - } - $maxCity = prev($nationCities); - } - - foreach($nationCities as $nationCity){ - if($nationCity['city'] == $maxCity['city']){ - break; - } - if(!$nationCity['supply']){ - continue; - } - if($nationCity['dev'] < 70){ - $targetCity = $nationCity; - break; - } - } - - foreach ($nationCities as $nationCity) { - if(!$nationCity['supply']){ - continue; - } - if(count($nationCity['generals']) == 0){ - continue; - } - if($maxDevCity === null || $maxDevCity['dev'] < $nationCity['dev']){ - $maxDevCity = $nationCity; - } - } - - if($targetCity === null || (count($targetCity['generals']) >= count($maxCity['generals']) - 1)){ - $targetCity = $minCity; - } - - if($maxDevCity['dev'] >= 95 && $targetCity['city'] != $maxDevCity['city'] && $targetCity['dev'] <= 70){ - $targetGeneral = $nationGenerals[Util::choiceRandom($maxDevCity['generals'])]; - if($targetGeneral['troop'] != 0){ - $commandList[EncodeCommand(0, $targetGeneral['no'], $targetCity['city'], 27)] = 2; - } - } - - if(count($targetCity['generals']) < count($maxCity['generals']) - 2){ - //세명 이상 차이나야 함 - $targetGeneral = $nationGenerals[Util::choiceRandom($maxCity['generals'])]; - if($targetGeneral['npc']==5){ - - } - else if($targetGeneral['npc']>=2 || $maxCity['dev'] >= 95 && $targetGeneral['troop'] == 0){ - //유저장은 의도가 있을 것이므로 삽나지 않는 이상 발령 안함! - $commandList[EncodeCommand(0, $targetGeneral['no'], $targetCity['city'], 27)] = 5; - } - - } - } - - // 병사있고 쌀있고 후방에 있는 장수 - if($frontCitiesID){ - $workRemain = 3; - foreach($nationGenerals as $nationGeneral){ - $generalCity = $nationCities[$nationGeneral['city']]??null; - if(!$generalCity){ - continue; - } - if($nationGeneral['crew'] < 2000){ - continue; - } - if($nationGeneral['rice'] < 700 * $tech){ - continue; - } - if($generalCity['front']){ - continue; - } - if($nationGeneral['train'] * $nationGeneral['atmos'] < 75 * 75){ - continue; - } - - if($nationGeneral['troop'] != 0){ - continue; - } - - $score = 5; - if($nationGeneral['npc']<2){ - $score *= 4; - } - - if(Util::randBool(0.3) && $frontImportantCitiesID){ - $targetCityID = Util::choiceRandom($frontImportantCitiesID); - } - else{ - $targetCityID = Util::choiceRandom($frontCitiesID); - } - - $command = EncodeCommand(0, $nationGeneral['no'], $targetCityID, 27); - - if($nationGeneral['npc']<2 && ($workRemain&2)){ - $workRemain ^= 2; - $commandList[$command] = $score; - } - else if($nationGeneral['npc']>=2 && ($workRemain&1)){ - $workRemain ^= 1; - $commandList[$command] = $score; - } - - if($workRemain <= 0){ - break; - } - } - } - - //병사 없고 인구없는 전방에 있는 장수 - if($frontCitiesID && $backupCitiesID){ - $workRemain = 3; - foreach($nationGenerals as $nationGeneral){ - $generalCity = $nationCities[$nationGeneral['city']]??null; - if(!$generalCity){ - continue; - } - if($nationGeneral['crew'] >= 1000){ - continue; - } - if($nationGeneral['rice'] < 700 * $tech){ - continue; - } - if(!$generalCity['front']){ - continue; - } - if($generalCity['pop'] - 33000 > $nationGeneral['leader']){ - continue; - } - if($nationGeneral['troop'] != 0){ - continue; - } - - $score = 5; - 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']){ - continue; - } - if (Util::randBool($targetCity['pop'] / $targetCity['pop2'])) { - break; - } - } - - - $command = EncodeCommand(0, $nationGeneral['no'], $targetCity['city'], 27); - - if($nationGeneral['npc']<2 && ($workRemain&2)){ - $workRemain ^= 2; - $commandList[$command] = $score; - } - else if($nationGeneral['npc']>=2 && ($workRemain&1)){ - $workRemain ^= 1; - $commandList[$command] = $score; - } - - if($workRemain <= 0){ - break; - } - } - } - - if(!$commandList)return 0; - return Util::choiceRandomUsingWeight($commandList); -} - -//종전하기, 지급율 -//$command = $fourth * 100000000 + $type * 100000 + $crew * 100 + 11; - -function Promotion($nation, $level) { - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - $connect=$db->get(); - - $lv = getNationChiefLevel($level); - - $admin = $gameStor->getValues(['scenario', 'killturn']); - - //우선 수뇌 해제 (승상 뺴고) - $query = "update general set level=1 where level<11 and level>4 and nation='$nation'"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - - $maxBelong = $db->queryFirstField('SELECT max(belong) FROM `general` WHERE nation=%i', $nation); - $maxBelong = min($maxBelong - 1, 3); - - //유저 후보 선택 - $query = "select no from general where nation='$nation' and npc<2 and level=1 and belong>=$maxBelong and killturn>='{$admin['killturn']}' order by rand() limit 0,1"; - $result = MYDB_query($query, $connect) or Error("Promotion_00 ".MYDB_error($connect),""); - $userCandidate = MYDB_fetch_array($result); - // 유저수뇌 안함 - //$userCandidate['no'] = 0; - - //NPC 후보 선택 - $query = "select no from general where nation='$nation' and npc>=2 and level=1 order by intel desc limit 0,1"; - $result = MYDB_query($query, $connect) or Error("Promotion_00 ".MYDB_error($connect),""); - $npcCandidate = MYDB_fetch_array($result); - - //현재 참모 - $query = "select no,intel,npc,killturn from general where nation='$nation' and level=11"; - $result = MYDB_query($query, $connect) or Error("Promotion_00 ".MYDB_error($connect),""); - $level11 = MYDB_fetch_array($result); - - //공석이거나 삭턴 유저 참모인 경우 - if($level11['no'] == 0 || ($level11['npc'] < 2 && $level11['killturn'] < $admin['killturn'])) { - if($userCandidate['no'] > 0) { - //기존 참모 해임 - $query = "update general set level=1 where nation='$nation' and level=11"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - //유저 후보 있으면 임명 - $query = "update general set level=11 where no='{$userCandidate['no']}'"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - } elseif($npcCandidate['no'] > 0) { - //기존 참모 해임 - $query = "update general set level=1 where nation='$nation' and level=11"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - //NPC 후보 있으면 임명 - $query = "update general set level=11 where no='{$npcCandidate['no']}'"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - } - } elseif($level11['npc'] >= 2 && $userCandidate['no'] > 0) { - //NPC 참모인데 삭턴 아닌 유저장이 있는 경우 - //기존 참모 해임 - $query = "update general set level=1 where nation='$nation' and level=11"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - //유저 후보 있으면 임명 - $query = "update general set level=11 where no='{$userCandidate['no']}'"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - } - - for($i=10; $i >= $lv; $i-=2) { - $i1 = $i; $i2 = $i - 1; - //무관임명 - $query = "select no from general where nation='$nation' and level=1 order by power desc limit 0,1"; - $result = MYDB_query($query, $connect) or Error("Promotion_00 ".MYDB_error($connect),""); - $level = MYDB_fetch_array($result); - $query = "update general set level={$i1} where no='{$level['no']}'"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - //문관임명 - $query = "select no from general where nation='$nation' and level=1 order by intel desc limit 0,1"; - $result = MYDB_query($query, $connect) or Error("Promotion_00 ".MYDB_error($connect),""); - $level = MYDB_fetch_array($result); - $query = "update general set level={$i2} where no='{$level['no']}'"; - MYDB_query($query, $connect) or Error("Promotion_02 ".MYDB_error($connect),""); - } -} - -function TaxRate($nation) { - $db = DB::db(); - $connect=$db->get(); - - //도시 - $query = "select city from city where nation='$nation'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $cityCount = MYDB_num_rows($result); - - if($cityCount == 0) { - $query = "update nation set war=0,rate=15 where nation='$nation'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - return 15; - } else { - $query = "select sum(pop)/sum(pop2)*100 as rate,(sum(agri)+sum(comm)+sum(secu)+sum(def)+sum(wall))/(sum(agri2)+sum(comm2)+sum(secu2)+sum(def2)+sum(wall2))*100 as dev from city where nation='$nation'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $devRate = MYDB_fetch_array($result); - - $avg = ($devRate['rate'] + $devRate['dev']) / 2; - - if($avg > 95) $rate = 25; - elseif($avg > 70) $rate = 20; - elseif($avg > 50) $rate = 15; - else $rate = 10; - - $query = "update nation set war=0,rate='$rate' where nation='$nation'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - return $rate; - } -} - -function GoldBillRate($nation, $rate, $gold_rate, $type, $gold) { - $db = DB::db(); - $connect=$db->get(); - - $incomeList = getGoldIncome($nation, $rate, $gold_rate, $type); - $income = $gold + $incomeList[0] + $incomeList[1]; - $outcome = getGoldOutcome($nation, 100); // 100%의 지급량 - $bill = intval($income / $outcome * 90); // 수입의 90% 만 지급 - - if($bill < 20) { $bill = 20; } - if($bill > 200) { $bill = 200; } - - $query = "update nation set bill='$bill' where nation='$nation'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); -} - -function RiceBillRate($nation, $rate, $rice_rate, $type, $rice) { - $db = DB::db(); - $connect=$db->get(); - - $incomeList = getRiceIncome($nation, $rate, $rice_rate, $type); - $income = $rice + $incomeList[0] + $incomeList[1]; - $outcome = getRiceOutcome($nation, 100); // 100%의 지급량 - $bill = intval($income / $outcome * 90); // 수입의 90% 만 지급 - - if($bill < 20) { $bill = 20; } - if($bill > 200) { $bill = 200; } - - $query = "update nation set bill='$bill' where nation='$nation'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); -} -