From d21fc4ab1d8abce0ef052ff7b339c16e99c3c477 Mon Sep 17 00:00:00 2001 From: hide_d Date: Sun, 12 Aug 2018 22:23:53 +0900 Subject: [PATCH] =?UTF-8?q?=EC=83=88=20=EC=A0=84=ED=88=AC=20=EC=97=94?= =?UTF-8?q?=EC=A7=84=20=EC=A4=80=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/process_war.ng.php | 442 +++++++++++++++++++++++++++++++++++++++++ hwe/process_war.php | 1 - hwe/sammo/WarUnit.php | 58 ++++++ 3 files changed, 500 insertions(+), 1 deletion(-) create mode 100644 hwe/process_war.ng.php create mode 100644 hwe/sammo/WarUnit.php diff --git a/hwe/process_war.ng.php b/hwe/process_war.ng.php new file mode 100644 index 00000000..a39bfe5a --- /dev/null +++ b/hwe/process_war.ng.php @@ -0,0 +1,442 @@ +getAll(); + //year, month + + $year = $admin['year']; + $month = $admin['month']; + + $attacker = new WarUnit($rawGeneral['no'], $rawGeneral['nation'], $year, $month); + + $deadAmount = [ + 'att'=>0, + 'def'=>0 + ]; +} + + +function CriticalScore2($score) { + $score = Util::round($score * (rand()%8 + 13)/10); // 1.3~2.0 + return $score; +} + +//0 0 : 100 100 이면 최고 무한대 차이 +//30 30 : 100 100 이면 최고 3.3배 차이 +//60 60 : 100 100 이면 최고 1.6배 차이 +function getCrew($crew, $youatmos, $mytrain) { + $ratio = $youatmos / $mytrain; + $crew = $crew * $ratio; + + return $crew; +} + +function getCrewtypeRice($crewtype, $tech) { + $cost = $crewtype->rice / 10; + return $cost * getTechCost($tech); +} + +////////////////////////////////////////////////////////////// +// 표준 공 / 수 반환 수치는 약 0이 되게 (100~550) +////////////////////////////////////////////////////////////// + +function getRate($admin, $type, $dtype) { + $t = "{$dtype}{$type}"; + return $admin[$t]; +} + +function addConflict($city, $nationID, $mykillnum) { + $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); + + $nationlist = []; + $killnum = [0]; + + list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']); + + $conflict = Json::decode($city['conflict']); + + if(!$conflict || $city['def'] == 0){ // 선타, 막타 보너스 + $mykillnum *= 1.05; + } + + if (!$conflict) { + $conflict[$nationID] = $mykillnum; + } + else if(key_exists($nationID, $conflict)){ + $conflict[$nationID] += $mykillnum; + arsort($conflict); + } + else{ + $conflict[$nationID] = $mykillnum; + arsort($conflict); + + $nation = getNationStaticInfo($nationID); + $josaYi = JosaUtil::pick($nation['name'], '이'); + pushWorldHistory(["●{$year}년 {$month}월:【분쟁】{$nation['name']}{$josaYi} {$city['name']} 공략에 가담하여 분쟁이 발생하고 있습니다."]); + } + + $rawConflict = Json::encode($conflict); + $city['conflict'] = $rawConflict; + + $db->update('city', [ + 'conflict'=>$rawConflict + ], 'city=%i',$city['city']); + + return $city; +} + +function DeleteConflict($nation) { + $db = DB::db(); + + foreach($db->queryAllLists('SELECT city, conflict FROM city WHERE conflict!=%s', '{}') as list($cityID, $rawConflict)){ + $conflict = Json::decode($rawConflict); + + if(!$conflict || !is_array($conflict)){ + continue; + } + if(!key_exists($nation, $conflict)){ + continue; + } + + unset($conflict[$nation]); + + $db->update('city', [ + 'conflict'=>Json::encode($conflict) + ], 'city=%i', $cityID); + } +} + +function getConquerNation($city) : int { + $conflict = Json::decode($city['conflict']); + return Util::array_first_key($conflict); +} + +function ConquerCity($admin, $general, $city, $nation, $destnation) { + '@phan-var array $city'; + $db = DB::db(); + $connect=$db->get(); + + $alllog = []; + $log = []; + $history = []; + + if($destnation['nation'] > 0) { + $destnationName = "{$destnation['name']}의"; + } else { + $destnationName = "공백지인"; + } + + $year = $admin['year']; + $month = $admin['month']; + + $josaUl = JosaUtil::pick($city['name'], '을'); + $josaYiNation = JosaUtil::pick($nation['name'], '이'); + $josaYiGen = JosaUtil::pick($general['name'], '이'); + $josaYiCity = JosaUtil::pick($city['name'], '이'); + $alllog[] = "●{$month}월:{$general['name']}{$josaYiGen} {$city['name']} 공략에 성공했습니다."; + $log[] = "{$city['name']} 공략에 성공했습니다."; + $history[] = "●{$year}년 {$month}월:【지배】{$nation['name']}{$josaYiNation} {$city['name']}{$josaUl} 지배했습니다."; + pushGeneralHistory($general, "●{$year}년 {$month}월:{$city['name']}{$josaUl} 함락시킴"); + pushNationHistory($nation, "●{$year}년 {$month}월:{$general['name']}{$josaYiGen} {$destnationName} {$city['name']}{$josaUl} 점령"); + pushNationHistory($destnation, "●{$year}년 {$month}월:{$nation['name']}{$general['name']}에 의해 {$city['name']}{$josaYiCity} 함락"); + + $query = "select city from city where nation='{$city['nation']}'"; + $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $citycount = MYDB_num_rows($result); + + // 국가 멸망시 + //TODO: 국가 멸망 코드를 별도로 작성 + if($citycount == 1 && $city['nation'] != 0) { + $query = "select nation,name,gold,rice from nation where nation='{$city['nation']}'"; + $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $losenation = MYDB_fetch_array($result); + + $josaYi = JosaUtil::pick($losenation['name'], '이'); + $josaUl = JosaUtil::pick($losenation['name'], '을'); + $history[] = "●{$year}년 {$month}월:【멸망】{$losenation['name']}{$josaYi} 멸망하였습니다."; + pushNationHistory($nation, "●{$year}년 {$month}월:{$losenation['name']}{$josaUl} 정복"); + + $query = "select no, nation from general where nation='{$general['nation']}' and level='12'"; + $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $ruler = MYDB_fetch_array($result); + + //다굴치는 나라들 전방설정을 위해 미리 얻어옴 + $query = "select you from diplomacy where me='{$losenation['nation']}' and state<2"; + $dipResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $dipCount = MYDB_num_rows($dipResult); + + $loseGeneralGold = 0; + $loseGeneralRice = 0; + //멸망국 장수들 역사 기록 및 로그 전달 + $josaYi = JosaUtil::pick($losenation['name'], '이'); + $genlog = ["{$losenation['name']}{$josaYi} 멸망했습니다."]; + + + // 국가 백업 + $oldNation = $db->queryFirstRow('SELECT * FROM nation WHERE nation=%i', $city['nation']); + $oldNationGenerals = $db->query('SELECT * FROM general WHERE nation=%i', $city['nation']); + $oldNation['generals'] = array_map(function($gen){ + //다른 코드와는 다르게 공용으로 쓰므로 남겨둠 + return $gen['no']; + }, $oldNationGenerals); + $oldNation['aux'] = Json::decode($oldNation['aux']); + + foreach($oldNationGenerals as $gen){ + + $loseGold = intdiv($gen['gold'] * (rand()%30+20), 100); + $loseRice = intdiv($gen['rice'] * (rand()%30+20), 100); + $genlog[1] = "●도주하며 금$loseGold 쌀$loseRice을 분실했습니다."; + + $query = "update general set gold=gold-{$loseGold},rice=rice-{$loseRice} where no={$gen['no']}"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + + pushGenLog($gen, $genlog); + + pushGeneralHistory($gen, "●{$year}년 {$month}월:{$losenation['name']}{$josaYi} 멸망"); + pushOldNationStop($gen['no'], $city['nation']); + + $loseGeneralGold += $loseGold; + $loseGeneralRice += $loseRice; + + //모두 등용장 발부 + if($nation['name'] == "강족" || $nation['name'] == "저족" || $nation['name'] == "흉노족" + || $nation['name'] == "남만족" || $nation['name'] == "산월족" || $nation['name'] == "오환족" + || $nation['name'] == "왜족") { + //등용장 미발부 + } elseif(Util::randBool(0.5)) { + $msg = ScoutMessage::buildScoutMessage($general['no'], $gen['no']); + if($msg){ + $msg->send(true); + } + } + + //NPC인 경우 10% 확률로 임관(엔장, 인재, 의병) + if($gen['npc'] >= 2 && $gen['npc'] <= 8 && rand() % 100 < 10) { + $commissionCommand = EncodeCommand(0, 0, $nation['nation'], 25); //임관 + $query = "update general set turn0='$commissionCommand' where no={$gen['no']}"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + } + } + unset($genlog[1]); + + // 승전국 보상 + $losenation['gold'] -= GameConst::$basegold; + $losenation['rice'] -= GameConst::$baserice; + if($losenation['gold'] < 0) { $losenation['gold'] = 0; } + if($losenation['rice'] < 0) { $losenation['rice'] = 0; } + + $losenation['gold'] += $loseGeneralGold; + $losenation['rice'] += $loseGeneralRice; + + $losenation['gold'] = intdiv($losenation['gold'], 2); + $losenation['rice'] = intdiv($losenation['gold'], 2); + + // 기본량 제외 금쌀50% + 장수들 분실 금쌀50% 흡수 + $query = "update nation set gold=gold+'{$losenation['gold']}',rice=rice+'{$losenation['rice']}' where nation='{$general['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + + //아국 수뇌부에게 로그 전달 + $query = "select no,name,nation from general where nation='{$general['nation']}' and level>='9'"; + $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $gencount = MYDB_num_rows($result); + $genlog[0] = "{$losenation['name']} 정복으로 금{$losenation['gold']} 쌀{$losenation['rice']}을 획득했습니다."; + for($i=0; $i < $gencount; $i++) { + $gen = MYDB_fetch_array($result); + pushGenLog($gen, $genlog); + } + + + //분쟁기록 모두 지움 + DeleteConflict($city['nation']); + // 전 장수 공헌 명성치 깎음 + $query = "update general set dedication=dedication*0.5,experience=experience*0.9 where nation='{$city['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + // 전 도시 공백지로 + $query = "update city set nation='0',gen1='0',gen2='0',gen3='0',conflict='{}',term=0 where nation='{$city['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + // 전 장수 소속 무소속으로, 재야로, 부대 탈퇴 + $query = "update general set nation='0',belong='0',level='0',troop='0' where nation='{$city['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + // 부대도 삭제 + $query = "delete from troop where nation='{$city['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + // 외교 삭제 + $query = "delete from diplomacy where me='{$city['nation']}' or you='{$city['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + + $db->insert('ng_old_nations', [ + 'server_id'=>UniqueConst::$serverID, + 'nation'=>$city['nation'], + 'data'=>Json::encode($oldNation) + ]); + // 국가 삭제 + $query = "delete from nation where nation='{$city['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + // 아까 얻어온 다굴국들 전방설정 + for($i=0; $i < $dipCount; $i++) { + $dip = MYDB_fetch_array($dipResult); + //전방설정 + SetNationFront($dip['you']); + } + // 멸망이 아니면 + } else { + // 태수,군사,시중은 일반으로... + $db->update('general',[ + 'level'=>1 + ], 'no IN %li',[$city['gen1'], $city['gen2'], $city['gen3']]); + + //수도였으면 긴급 천도 + if(isset($destnation['capital']) && $destnation['capital'] == $city['city']) { + $minCity = findNextCapital($city['city'], $destnation['nation']); + + $minCityName = CityConst::byID($minCity)->name; + + $josaYi = JosaUtil::pick($destnation['name'], '이'); + $history[] = "●{$year}년 {$month}월:【긴급천도】{$destnation['name']}{$josaYi} 수도가 함락되어 $minCityName으로 긴급천도하였습니다."; + + //아국 수뇌부에게 로그 전달 + $query = "select no,name,nation from general where nation='{$destnation['nation']}' and level>='5'"; + $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $gencount = MYDB_num_rows($result); + $genlog = ["●수도가 함락되어 $minCityName으로 긴급천도합니다."]; + for($i=0; $i < $gencount; $i++) { + $gen = MYDB_fetch_array($result); + pushGenLog($gen, $genlog); + } + //천도 + $query = "update nation set capital='$minCity',gold=gold*0.5,rice=rice*0.5 where nation='{$destnation['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + //보급도시로 만듬 + $query = "update city set supply=1 where city='$minCity'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + //수뇌부 이동 + $query = "update general set city='$minCity' where nation='{$destnation['nation']}' and level>='5'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + //장수 사기 감소 + $query = "update general set atmos=atmos*0.8 where nation='{$destnation['nation']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + + refreshNationStaticInfo(); + } + } + + $general['atmos'] *= 1.1; //사기 증가 + if($general['atmos'] > GameConst::$maxAtmosByWar) { $general['atmos'] = GameConst::$maxAtmosByWar; } + + $conquerNation = getConquerNation($city); + + if($conquerNation == $general['nation']) { + // 이동 및 사기 변경 + $query = "update general set city='{$city['city']}',atmos='{$general['atmos']}',killnum=killnum+1 where no='{$general['no']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + if($city['level'] > 3) { + // 도시 소속 변경, 태수,군사,시중 초기화 + $query = "update city set supply=1,conflict='{}',term=0,agri=agri*0.7,comm=comm*0.7,secu=secu*0.7,def=1000,wall=1000,nation='{$general['nation']}',gen1=0,gen2=0,gen3=0 where city='{$city['city']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + } else { + // 도시 소속 변경, 태수,군사,시중 초기화 + $query = "update city set supply=1,conflict='{}',term=0,agri=agri*0.7,comm=comm*0.7,secu=secu*0.7,def=def2/2,wall=wall2/2,nation='{$general['nation']}',gen1=0,gen2=0,gen3=0 where city='{$city['city']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + } + //전방설정 + SetNationFront($nation['nation']); + SetNationFront($destnation['nation']); + } else { + $query = "select name,nation from nation where nation='$conquerNation'"; + $conquerResult = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + $conquerNationArray = MYDB_fetch_array($conquerResult); + + + + $josaUl = JosaUtil::pick($city['name'], '을'); + $josaYi = JosaUtil::pick($conquerNationArray['name'], '이'); + $history[] = "●{$year}년 {$month}월:【분쟁협상】{$conquerNationArray['name']}{$josaYi} 영토분쟁에서 우위를 점하여 {$city['name']}{$josaUl} 양도받았습니다."; + pushNationHistory($nation, "●{$year}년 {$month}월:{$city['name']}{$josaUl} {$conquerNationArray['name']}양도"); + pushNationHistory($conquerNationArray, "●{$year}년 {$month}월:{$nation['name']}에서 {$city['name']}{$josaUl} 양도 받음"); + // 이동X 및 사기 변경 + $query = "update general set atmos='{$general['atmos']}',killnum=killnum+1 where no='{$general['no']}'"; + MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); + + $query = [ + 'supply'=>1, + 'term'=>0, + 'conflict'=>'{}', + 'agri'=>$db->sqleval('agri*0.7'), + 'comm'=>$db->sqleval('comm*0.7'), + 'secu'=>$db->sqleval('secu*0.7'), + 'nation'=>$conquerNation, + 'gen1'=>0, + 'gen2'=>0, + 'gen3'=>0 + ]; + if($city['level'] > 3) { + $query['def'] = 1000; + $query['wall'] = 1000; + } else { + // 도시 소속 변경, 태수,군사,시중 초기화 + $query['def'] = $db->sqleval('def2/2'); + $query['wall'] = $db->sqleval('wall2/2'); + } + $db->update('city', $query, 'city=%i', (int)$city['city']); + //전방설정 + SetNationFront($destnation['nation']); + SetNationFront($conquerNation); + } + + pushGenLog($general, $log); + pushGeneralPublicRecord($alllog, $year, $month); + pushWorldHistory($history); +} + +function findNextCapital(int $capitalID, int $nationID):int{ + $distList = searchDistance($capitalID, 99, true); + + $cities = []; + foreach( + DB::db()->query( + 'SELECT city, pop FROM city WHERE nation=%i and city!=%i', + $nationID, + $capitalID + ) as $row + ){ + $cities[$row['city']] = $row['pop']; + }; + + + + foreach($distList as $dist=>$distSubList){ + $maxCityPop = 0; + $minCity = 0; + + foreach($distSubList as $cityID){ + if(!key_exists($cityID, $cities)){ + continue; + } + $cityPop = $cities[$cityID]; + + if($cityPop < $maxCityPop){ + continue; + } + $minCity = $cityID; + $maxCityPop = $cityPop; + } + + if($minCity){ + return $minCity; + } + } + throw new \RuntimeException('도시가 남지 않았는데 긴천을 시도하고 있습니다'); +} \ No newline at end of file diff --git a/hwe/process_war.php b/hwe/process_war.php index f2d8e78c..80826e7d 100644 --- a/hwe/process_war.php +++ b/hwe/process_war.php @@ -1,7 +1,6 @@ $general'; diff --git a/hwe/sammo/WarUnit.php b/hwe/sammo/WarUnit.php new file mode 100644 index 00000000..69672c15 --- /dev/null +++ b/hwe/sammo/WarUnit.php @@ -0,0 +1,58 @@ +rawGeneral = $rawGeneral; + $this->logger = new ActionLogger($rawGeneral['no'], $rawGeneral['nation'], $year, $month); + $this->crewType = GameUnitConst::byID($rawGeneral['crewtype']); + } + + function getCrewType():GameUnitConst{ + return $this->crewType; + } + + function getLogger():ActionLogger{ + return $this->logger; + } + + function getSpecialDomestic():int{ + return $this->rawGeneral['special']; + } + + function getSpecialWar():int{ + return $this->rawGeneral['special2']; + } + + function getItem():int{ + return $this->rawGeneral['item']; + } + + function getMaxPhase():int{ + $phase = $this->getCrewType()->speed; + if($this->getSpecialWar() == 60){ + $phase += 1; + } + return $phase; + } + + function doUseBattleInitItem():bool{ + $item = $this->getItem(); + + + } + + + + +} \ No newline at end of file