From aa19ae129b6850a732218e4dfe0216e415638c13 Mon Sep 17 00:00:00 2001 From: hide_d Date: Sat, 20 Oct 2018 16:45:57 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=84=ED=88=AC=ED=83=9C=EC=84=B8,=20?= =?UTF-8?q?=EC=B2=A9=EB=B3=B4=20=EC=B6=94=EA=B0=80,=20=EA=B8=B0=EC=A1=B4?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=9D=BC=EB=B6=80=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/func_process.php | 152 --------------- hwe/sammo/CityConstBase.php | 2 - hwe/sammo/Command/General/che_강행.php | 2 +- hwe/sammo/Command/General/che_견문.php | 8 +- hwe/sammo/Command/General/che_사기진작.php | 2 +- hwe/sammo/Command/General/che_이동.php | 2 +- hwe/sammo/Command/General/che_전투태세.php | 134 +++++++++++++ hwe/sammo/Command/General/che_첩보.php | 181 ++++++++++++++++++ hwe/sammo/Command/General/che_훈련.php | 2 +- hwe/sammo/Constraint/NotOccupiedDestCity.php | 37 ++++ .../{NotSameCity.php => NotSameDestCity.php} | 2 +- hwe/sammo/Constraint/ReqCityTrader.php | 32 ++++ .../Constraint/ReqGeneralAtmosMargin.php | 4 +- .../Constraint/ReqGeneralTrainMargin.php | 4 +- hwe/sammo/Constraint/SuppliedCity.php | 2 +- .../TextDecoration/SightseeingMessage.php | 20 +- hwe/sql/schema.sql | 70 ++++--- src/sammo/Util.php | 36 +++- 18 files changed, 476 insertions(+), 216 deletions(-) create mode 100644 hwe/sammo/Command/General/che_전투태세.php create mode 100644 hwe/sammo/Command/General/che_첩보.php create mode 100644 hwe/sammo/Constraint/NotOccupiedDestCity.php rename hwe/sammo/Constraint/{NotSameCity.php => NotSameDestCity.php} (94%) create mode 100644 hwe/sammo/Constraint/ReqCityTrader.php diff --git a/hwe/func_process.php b/hwe/func_process.php index 5e1c9e96..e616ed6e 100644 --- a/hwe/func_process.php +++ b/hwe/func_process.php @@ -399,158 +399,6 @@ function process_11(&$general, $type) { $actLog->pushGeneralActionLog($log, ActionLogger::RAWTEXT); } -function process_15(&$general) { - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - $connect=$db->get(); - - $log = []; - $alllog = []; - $history = []; - $date = substr($general['turntime'],11,5); - - $admin = $gameStor->getValues(['year', 'month']); - - $query = "select nation,tech from nation where nation='{$general['nation']}'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $nation = MYDB_fetch_array($result); - - $query = "select nation,supply from city where city='{$general['city']}'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $city = MYDB_fetch_array($result); - - if($general['term']%100 == 15) { - $term = intdiv($general['term'], 100) + 1; - $code = $term * 100 + 15; - } else { - $term = 1; - $code = 100 + 15; - } - - $cost = Util::round($general['crew']/100 * 3 * getTechCost($nation['tech'])); - - if($general['level'] == 0) { - $log[] = "●{$admin['month']}월:재야입니다. 전투태세 실패. <1>$date"; - } elseif($city['nation'] != $general['nation']) { - $log[] = "●{$admin['month']}월:아국이 아닙니다. 전투태세 실패. <1>$date"; -// } elseif($city['supply'] == 0) { -// $log[] = "●{$admin['month']}월:고립된 도시입니다. 전투태세 실패. <1>$date"; - } elseif($general['crew'] == 0) { - $log[] = "●{$admin['month']}월:병사가 없습니다. 전투태세 실패. <1>$date"; - } elseif($general['atmos'] >= 90 && $general['train'] >= 90) { - $log[] = "●{$admin['month']}월:이미 병사들은 날쌔고 용맹합니다. <1>$date"; - } elseif($general['gold'] < $cost) { - $log[] = "●{$admin['month']}월:자금이 모자랍니다. 전투태세 실패. <1>$date"; - } elseif($term < 3) { - $log[] = "●{$admin['month']}월:병사들을 열심히 훈련중... ({$term}/3) <1>$date"; - - $query = "update general set resturn='ONGOING',term={$code} where no='{$general['no']}'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - } else { - //기술로 가격 - $gold = $general['gold'] - $cost; - - $log[] = "●{$admin['month']}월:전투태세 완료! <1>$date"; - $exp = 100 * 3; - $ded = 70 * 3; - // 숙련도 증가 - addGenDex($general['no'], GameConst::$maxAtmosByCommand, GameConst::$maxTrainByCommand, $general['crewtype'], Util::round($general['crew']/100 * 3)); - // 성격 보정 - $exp = CharExperience($exp, $general['personal']); - $ded = CharDedication($ded, $general['personal']); - - // 훈련,사기치 변경 // 자금 감소 // 경험치 상승 // 공헌도, 명성 상승 - $general['leader2']+=3; - $query = "update general set resturn='SUCCESS',term='0',atmos='95',train='95',gold='$gold',leader2='{$general['leader2']}',dedication=dedication+'$ded',experience=experience+'$exp' where no='{$general['no']}'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - - $log = checkAbility($general, $log); - $log = uniqueItem($general, $log); - } - - pushGenLog($general, $log); -} - -function process_16(&$general) { - $db = DB::db(); - $gameStor = KVStorage::getStorage($db, 'game_env'); - $connect=$db->get(); - - $log = []; - $alllog = []; - $history = []; - $date = substr($general['turntime'],11,5); - - $admin = $gameStor->getValues(['startyear', 'year', 'month']); - - $query = "select nation,war,sabotagelimit,tech from nation where nation='{$general['nation']}'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $nation = MYDB_fetch_array($result); - - $query = "select nation,supply 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']); - $destination = $command[1]; - - $query = "select * from city where city='$destination'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $destcity = MYDB_fetch_array($result); - - $query = "select nation,sabotagelimit,tech from nation where nation='{$destcity['nation']}'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $dnation = MYDB_fetch_array($result); - - $query = "select state from diplomacy where me='{$general['nation']}' and you='{$destcity['nation']}'"; - $result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - $dip = MYDB_fetch_array($result); - - if(key_exists($destination, CityConst::byID($general['city'])->path)){ - $nearCity = true; - } - else{ - $nearCity = false; - } - - $josaRo = JosaUtil::pick($destcity['name'], '로'); - if($admin['year'] < $admin['startyear']+3) { - $log[] = "●{$admin['month']}월:현재 초반 제한중입니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; -// } elseif($city['supply'] == 0) { -// $log[] = "●{$admin['month']}월:고립된 도시입니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif(!$nearCity) { - $log[] = "●{$admin['month']}월:인접도시가 아닙니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($general['level'] == 0) { - $log[] = "●{$admin['month']}월:재야입니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($general['crew'] <= 0) { - $log[] = "●{$admin['month']}월:병사가 없습니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($general['rice'] <= Util::round($general['crew']/100)) { - $log[] = "●{$admin['month']}월:군량이 모자랍니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($dip['state'] != 0) { - $log[] = "●{$admin['month']}월:교전중인 국가가 아닙니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($general['nation'] != $city['nation']) { - $log[] = "●{$admin['month']}월:본국에서만 출병가능합니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($nation['war'] == 1) { - $log[] = "●{$admin['month']}월:현재 전쟁 금지입니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - } elseif($general['nation'] == $destcity['nation']) { - $log[] = "●{$admin['month']}월:본국입니다. {$destcity['name']}{$josaRo} 출병 실패. <1>$date"; - pushGenLog($general, $log); - process_21($general); - return; - } else { - // 전쟁 표시 - $query = "update city set state=43,term=3 where city='{$destcity['city']}'"; - MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),""); - // 숙련도 증가 - addGenDex($general['no'], GameConst::$maxAtmosByCommand, GameConst::$maxTrainByCommand, $general['crewtype'], Util::round($general['crew']/100)); - // 전투 처리 - processWar($general, $destcity); - $log = uniqueItem($general, $log); - } - - pushGenLog($general, $log); -} - function process_31(&$general) { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); diff --git a/hwe/sammo/CityConstBase.php b/hwe/sammo/CityConstBase.php index 5b6005cf..38ab1ebe 100644 --- a/hwe/sammo/CityConstBase.php +++ b/hwe/sammo/CityConstBase.php @@ -333,12 +333,10 @@ class CityConstBase{ $queries = array_map(function(CityInitialDetail $city){ $initValue = static::$buildInit[$city->level]; - $path = join('|', array_keys($city->path)); return [ 'city'=>$city->id, 'name'=>$city->name, 'level'=>$city->level, - 'path'=>$path, 'pop2'=>$city->population, 'agri2'=>$city->agriculture, 'comm2'=>$city->commerce, diff --git a/hwe/sammo/Command/General/che_강행.php b/hwe/sammo/Command/General/che_강행.php index 4deee6e1..3e2d6cdb 100644 --- a/hwe/sammo/Command/General/che_강행.php +++ b/hwe/sammo/Command/General/che_강행.php @@ -34,7 +34,7 @@ class che_강행 extends Command\GeneralCommand{ [$reqGold, $reqRice] = $this->getCost(); $this->runnableConstraints=[ - ['NotSameCity'], + ['NotSameDestCity'], ['NearCity', 3], ['ReqGeneralGold', $reqGold], ['ReqGeneralRice', $reqRice], diff --git a/hwe/sammo/Command/General/che_견문.php b/hwe/sammo/Command/General/che_견문.php index 495b90b1..5265e2c9 100644 --- a/hwe/sammo/Command/General/che_견문.php +++ b/hwe/sammo/Command/General/che_견문.php @@ -81,19 +81,19 @@ class che_견문 extends Command\GeneralCommand{ } if($type & SightseeingMessage::IncGold){ $general->increaseVar('gold', 300); - $text = str_replace(':amount:', '300', $text); + $text = str_replace(':goldAmount:', '300', $text); } if($type & SightseeingMessage::IncRice){ $general->increaseVar('rice', 300); - $text = str_replace(':amount:', '300', $text); + $text = str_replace(':riceAmount:', '300', $text); } if($type & SightseeingMessage::DecGold){ $general->increaseVarWithLimit('gold', -200, 0); - $text = str_replace(':amount:', '200', $text); + $text = str_replace(':goldAmount:', '200', $text); } if($type & SightseeingMessage::DecRice){ $general->increaseVarWithLimit('rice', -200, 0); - $text = str_replace(':amount:', '200', $text); + $text = str_replace(':riceAmount:', '200', $text); } if($type & SightseeingMessage::Wounded){ $general->increaseVarWithLimit('injury', Util::randRangeInt(10, 20), null, 80); diff --git a/hwe/sammo/Command/General/che_사기진작.php b/hwe/sammo/Command/General/che_사기진작.php index 7f599dd2..d83b701f 100644 --- a/hwe/sammo/Command/General/che_사기진작.php +++ b/hwe/sammo/Command/General/che_사기진작.php @@ -37,7 +37,7 @@ class che_사기진작 extends Command\GeneralCommand{ ['ReqGeneralCrew'], ['ReqGeneralGold', $reqGold], ['ReqGeneralRice', $reqRice], - ['ReqGeneralAtmosMargin'], + ['ReqGeneralAtmosMargin', GameConst::$maxAtmosByCommand], ]; } diff --git a/hwe/sammo/Command/General/che_이동.php b/hwe/sammo/Command/General/che_이동.php index 9ecf7f00..dc72253c 100644 --- a/hwe/sammo/Command/General/che_이동.php +++ b/hwe/sammo/Command/General/che_이동.php @@ -34,7 +34,7 @@ class che_이동 extends Command\GeneralCommand{ [$reqGold, $reqRice] = $this->getCost(); $this->runnableConstraints=[ - ['NotSameCity'], + ['NotSameDestCity'], ['NearCity', 1], ['ReqGeneralGold', $reqGold], ['ReqGeneralRice', $reqRice], diff --git a/hwe/sammo/Command/General/che_전투태세.php b/hwe/sammo/Command/General/che_전투태세.php new file mode 100644 index 00000000..a638de4d --- /dev/null +++ b/hwe/sammo/Command/General/che_전투태세.php @@ -0,0 +1,134 @@ +generalObj; + + $this->setCity(); + $this->setNation(); + + [$reqGold, $reqRice] = $this->getCost(); + + $this->runnableConstraints=[ + ['NoNeutral'], + ['NoWanderingNation'], + ['OccupiedCity'], + ['ReqGeneralCrew'], + ['ReqGeneralGold', $reqGold], + ['ReqGeneralRice', $reqRice], + ['ReqGeneralTrainMargin', GameConst::$maxTrainByCommand - 10], + ['ReqGeneralAtmosMargin', GameConst::$maxAtmosByCommand - 10], + ]; + + } + + protected function argTest():bool{ + $this->arg = null; + return true; + } + + public function getCost():array{ + $crew = $this->getVar('crew'); + $techCost = getTechCost($this->nation['tech']); + return [Util::round($crew / 100 * 3 * $techCost), 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(); + + $general = $this->generalObj; + $date = substr($general->getVar('turntime'),11,5); + + $lastTurn = $general->getLastTurn(); + $turnResult = new LastTurn(static::getName(), $this->arg); + + if($lastTurn->getCommand() != static::getName()){ + $turnResult->setTerm(1); + } + else if($lastTurn->getTerm() == 3){ + $turnResult->setTerm(1); + } + else if($lastTurn->getTerm() < 3){ + $turnResult->setTerm($lastTurn->getTerm()+1); + } + else{ + throw new MustNotBeReachedException('전투 태세는 1~3까지만 가능함'); + } + + $term = $turnResult->getTerm(); + + + $logger = $general->getLogger(); + + if($term < 3){ + $logger->pushGeneralActionLog("병사들을 열심히 훈련중... ({$term}/3) <1>$date"); + $general->setResultTurn($turnResult); + $general->applyDB($db); + + return true; + } + + $logger->pushGeneralActionLog("전투태세 완료! ({$term}/3) <1>$date"); + + $general->increaseVarWithLimit('train', 0, GameConst::$maxTrainByCommand - 5); //95보다 높으면 '깎이지는 않음' + $general->increaseVarWithLimit('atmos', 0, GameConst::$maxAtmosByCommand - 5); + + $exp = 100 * 3; + $ded = 70 * 3; + + $exp = $general->onPreGeneralStatUpdate($general, 'experience', $exp); + $ded = $general->onPreGeneralStatUpdate($general, 'dedication', $ded); + + $general->increaseVar('experience', $exp); + $general->increaseVar('dedication', $ded); + + $crew = $general->getVar('crew'); + + $general->addDex($general->getCrewTypeObj(), $crew / 100 * 3, false); + + $general->increaseVar('leader2', 3); + $general->setResultTurn($turnResult); + $general->checkStatChange(); + $general->applyDB($db); + + uniqueItemEx($general->getID(), $logger); + + 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..691ce27a --- /dev/null +++ b/hwe/sammo/Command/General/che_첩보.php @@ -0,0 +1,181 @@ +generalObj; + + $this->setCity(); + $this->setNation(['tech']); + $this->setDestCity($this->arg['destCityID'], []); + $this->setDestNation($this->destCity['nation'], ['tech']); + + [$reqGold, $reqRice] = $this->getCost(); + + $this->runnableConstraints=[ + ['NotOccupiedDestCity'], + ['ReqGeneralGold', $reqGold], + ['ReqGeneralRice', $reqRice], + ]; + } + + protected function argTest():bool{ + if(!key_exists('destCityID', $this->arg)){ + return false; + } + if(!key_exists($this->arg['destCityID'], CityConst::all())){ + return false; + } + $this->arg = [ + 'destCityID'=>$this->arg['destCityID'] + ]; + return true; + } + + public function getCost():array{ + $env = $this->env; + return [$env['develcost'], 0]; + } + + public function getPreReqTurn():int{ + return 0; + } + + public function getPostReqTurn():int{ + return 0; + } + + public function getFailString():string{ + $commandName = $this->getName(); + $failReason = $this->testRunnable(); + if($failReason === null){ + throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); + } + $destCityName = CityConst::byID($this->arg['destCityID'])->name; + return "{$failReason} {$destCityName}에 {$commandName} 실패."; + } + + 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); + + $destCity = $this->destCity; + + $destCityName = $destCity['name']; + $destCityID = $destCity['city']; + $destNationID = $destCity['nation']; + $josaUl = JosaUtil::pick($destCityName, '을'); + + $logger = $general->getLogger(); + + $dist = searchDistance($general->getCityID(), 2, false)[$destCityID]??3; + + $destCityGeneralList = $db->query('SELECT crew, crewtype FROM general WHERE city = %i AND nation = %i'); + $totalCrew = Util::arraySum($destCityGeneralList, 'crew'); + $totalGenCnt = count($destCityGeneralList); + $byCrewType = Util::arrayGroupBy($destCityGeneralList, 'crewtype'); + + $popText = number_format($destCity['pop']); + $trustText = number_format($destCity['trust'], 1); + $agriText = number_format($destCity['agri']); + $commText = number_format($destCity['comm']); + $secuText = number_format($destCity['secu']); + $defText = number_format($destCity['def']); + $wallText = number_format($destCity['wall']); + + $cityBrief = "【{$destCityName}】주민:{$popText}, 민심:{$trustText}, 장수:{$totalGenCnt}, 병력:{$totalCrew}"; + $cityDevel = "【첩보】농업:{$agriText}, 상업:{$commText}, 치안:{$secuText}, 수비:{$defText}, 성벽:{$wallText}"; + + $logger->pushGeneralActionLog("누군가가 {$destCityName}{$josaUl} 살피는 것 같습니다."); + if($dist < 1){ + $logger->pushGeneralActionLog("{$destCityName}의 정보를 많이 얻었습니다. <1>$date"); + $logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT); + $logger->pushGeneralActionLog($cityDevel, ActionLogger::RAWTEXT); + $logger->pushGeneralActionLog('【병종】 '. join(' ', Util::mapWithKey(function($crewType, $value){ + $crewTypeText = mb_substr(GameUnitConst::byID($crewType)->name, 0, 2); + $cnt = count($value); + return "{$crewTypeText}:{$cnt}"; + })), ActionLogger::RAWTEXT); + + if($this->destNation['nation'] && $general->getNationID()){ + $techDiff = floor($this->destNation['tech']) - floor($this->nation['tech']); + if($techDiff >= 1000){ + $techText = '↑압도'; + } + else if($techDiff >= 250){ + $techText = '▲우위'; + } + else if($techDiff >= -250){ + $techText = '↕대등'; + } + else if($techDiff >= -1000){ + $techText = '▼열위'; + } + else{ + $techText = '↓미미'; + } + $logger->pushGeneralActionLog("【{$this->destNation['name']}】아국대비기술:{$techText}"); + } + + } + else if($dist == 2){ + $logger->pushGeneralActionLog("{$destCityName}의 정보를 어느 정도 얻었습니다. <1>$date"); + $logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT); + $logger->pushGeneralActionLog($cityDevel, ActionLogger::RAWTEXT); + } + else{ + $logger->pushGeneralActionLog("{$destCityName}의 소문만 들을 수 있었습니다. <1>$date"); + $logger->pushGeneralActionLog($cityBrief, ActionLogger::RAWTEXT); + } + + $exp = Util::randRangeInt(1, 100); + $ded = Util::randRangeInt(1, 70); + + $exp = $general->onPreGeneralStatUpdate($general, 'experience', $exp); + $ded = $general->onPreGeneralStatUpdate($general, 'dedication', $ded); + + [$reqGold, $reqRice] = $this->getCost(); + $general->increaseVarWithLimit('gold', -$reqGold, 0); + $general->increaseVarWithLimit('rice', -$reqRice, 0); + $general->increaseVar('experience', $exp); + $general->increaseVar('dedication', $ded); + $general->increaseVar('leader2', 1); + $general->setResultTurn(new LastTurn(static::getName(), $this->arg)); + $general->checkStatChange(); + $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 index 3ef9f87c..20bca756 100644 --- a/hwe/sammo/Command/General/che_훈련.php +++ b/hwe/sammo/Command/General/che_훈련.php @@ -34,7 +34,7 @@ class che_훈련 extends Command\GeneralCommand{ ['NoWanderingNation'], ['OccupiedCity'], ['ReqGeneralCrew'], - ['ReqGeneralTrainMargin'], + ['ReqGeneralTrainMargin', GameConst::$maxTrainByCommand], ]; } diff --git a/hwe/sammo/Constraint/NotOccupiedDestCity.php b/hwe/sammo/Constraint/NotOccupiedDestCity.php new file mode 100644 index 00000000..fdcc2aa8 --- /dev/null +++ b/hwe/sammo/Constraint/NotOccupiedDestCity.php @@ -0,0 +1,37 @@ +general)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require nation in general"); + } + + if(!key_exists('nation', $this->destCity)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require nation in city"); + } + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + if($this->destCity['nation'] == $this->general['nation']){ + return true; + } + + $this->reason = "아국입니다."; + return false; + } +} \ No newline at end of file diff --git a/hwe/sammo/Constraint/NotSameCity.php b/hwe/sammo/Constraint/NotSameDestCity.php similarity index 94% rename from hwe/sammo/Constraint/NotSameCity.php rename to hwe/sammo/Constraint/NotSameDestCity.php index 02d19129..a0c41502 100644 --- a/hwe/sammo/Constraint/NotSameCity.php +++ b/hwe/sammo/Constraint/NotSameDestCity.php @@ -2,7 +2,7 @@ namespace sammo\Constraint; -class NearCity extends Constraint{ +class NotSameDestCity extends Constraint{ const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_DEST_CITY; public function checkInputValues(bool $throwExeception=true){ diff --git a/hwe/sammo/Constraint/ReqCityTrader.php b/hwe/sammo/Constraint/ReqCityTrader.php new file mode 100644 index 00000000..83ab0793 --- /dev/null +++ b/hwe/sammo/Constraint/ReqCityTrader.php @@ -0,0 +1,32 @@ +city)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require trade in city"); + } + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + if($this->city['trade'] !== null){ + return true; + } + + $this->reason = "도시에 상인이 없습니다."; + return false; + } +} \ No newline at end of file diff --git a/hwe/sammo/Constraint/ReqGeneralAtmosMargin.php b/hwe/sammo/Constraint/ReqGeneralAtmosMargin.php index 23dee07f..51555dae 100644 --- a/hwe/sammo/Constraint/ReqGeneralAtmosMargin.php +++ b/hwe/sammo/Constraint/ReqGeneralAtmosMargin.php @@ -4,7 +4,7 @@ namespace sammo\Constraint; use sammo\GameConst; class ReqGeneralAtmosMargin extends Constraint{ - const REQ_VALUES = Constraint::REQ_GENERAL; + const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_INT_ARG; public function checkInputValues(bool $throwExeception=true){ if(!parent::checkInputValues($throwExeception) && !$throwException){ @@ -23,7 +23,7 @@ class ReqGeneralAtmosMargin extends Constraint{ $this->checkInputValues(); $this->tested = true; - if($this->general['atmos'] < GameConst::$maxAtmosByCommand){ + if($this->general['atmos'] < $this->arg){ return true; } diff --git a/hwe/sammo/Constraint/ReqGeneralTrainMargin.php b/hwe/sammo/Constraint/ReqGeneralTrainMargin.php index e02106f4..4cde1a55 100644 --- a/hwe/sammo/Constraint/ReqGeneralTrainMargin.php +++ b/hwe/sammo/Constraint/ReqGeneralTrainMargin.php @@ -4,7 +4,7 @@ namespace sammo\Constraint; use sammo\GameConst; class ReqGeneralTrainMargin extends Constraint{ - const REQ_VALUES = Constraint::REQ_GENERAL; + const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_INT_ARG; public function checkInputValues(bool $throwExeception=true){ if(!parent::checkInputValues($throwExeception) && !$throwException){ @@ -23,7 +23,7 @@ class ReqGeneralTrainMargin extends Constraint{ $this->checkInputValues(); $this->tested = true; - if($this->general['train'] < GameConst::$maxTrainByCommand){ + if($this->general['train'] < $this->arg){ return true; } diff --git a/hwe/sammo/Constraint/SuppliedCity.php b/hwe/sammo/Constraint/SuppliedCity.php index 5530126f..86144d2f 100644 --- a/hwe/sammo/Constraint/SuppliedCity.php +++ b/hwe/sammo/Constraint/SuppliedCity.php @@ -2,7 +2,7 @@ namespace sammo\Constraint; -class NoWanderingNation extends Constraint{ +class SuppliedCity extends Constraint{ const REQ_VALUES = Constraint::REQ_CITY; public function checkInputValues(bool $throwExeception=true){ diff --git a/hwe/sammo/TextDecoration/SightseeingMessage.php b/hwe/sammo/TextDecoration/SightseeingMessage.php index aa0430b7..a9458e16 100644 --- a/hwe/sammo/TextDecoration/SightseeingMessage.php +++ b/hwe/sammo/TextDecoration/SightseeingMessage.php @@ -47,17 +47,17 @@ class SightseeingMessage{ '거리에서 글 모르는 아이들을 모아 글을 가르쳤습니다.', ]], 2], [[self::IncExp|self::IncGold,[ - '지나가는 행인에게서 금을 :amount: 받았습니다.', + '지나가는 행인에게서 금을 :goldAmount: 받았습니다.', ]], 1], [[self::IncExp|self::IncRice,[ - '지나가는 행인에게서 쌀을 :amount: 받았습니다.', + '지나가는 행인에게서 쌀을 :riceAmount: 받았습니다.', ]], 1], [[self::IncExp|self::DecGold,[ - '산적을 만나 금 :amount:을 빼앗겼습니다.', - '돈을 :amount: 빌려주었다가 떼어먹혔습니다.', + '산적을 만나 금 :goldAmount:을 빼앗겼습니다.', + '돈을 :goldAmount: 빌려주었다가 떼어먹혔습니다.', ]], 1], [[self::IncExp|self::DecRice,[ - '쌀을 :amount: 빌려주었다가 떼어먹혔습니다.', + '쌀을 :riceAmount: 빌려주었다가 떼어먹혔습니다.', ]], 1], [[self::IncExp|self::Wounded,[ '호랑이에게 물려 다쳤습니다.', @@ -74,17 +74,17 @@ class SightseeingMessage{ '위기에 빠진 사람을 구하다가 죽을뻔 했습니다.', ]], 1], [[self::IncHeavyExp|self::IncPower|self::IncGold,[ - '산적과 싸워 금 :amount:을 빼앗았습니다.', + '산적과 싸워 금 :goldAmount:을 빼앗았습니다.', ]], 1], [[self::IncHeavyExp|self::IncPower|self::IncRice,[ - '호랑이를 잡아 고기 :amount:을 얻었습니다.', - '곰을 잡아 고기 :amount:을 얻었습니다.', + '호랑이를 잡아 고기 :riceAmount:을 얻었습니다.', + '곰을 잡아 고기 :riceAmount:을 얻었습니다.', ]], 1], [[self::IncHeavyExp|self::IncIntel|self::IncGold,[ - '돈을 빌려주었다가 이자 :amount:을 받았습니다.', + '돈을 빌려주었다가 이자 :goldAmount:을 받았습니다.', ]], 1], [[self::IncHeavyExp|self::IncIntel|self::IncRice,[ - '쌀을 빌려주었다가 이자 300을 받았습니다.', + '쌀을 빌려주었다가 이자 :riceAmount:을 받았습니다.', ]], 1], ]; diff --git a/hwe/sql/schema.sql b/hwe/sql/schema.sql index b4526a47..c1bab5c4 100644 --- a/hwe/sql/schema.sql +++ b/hwe/sql/schema.sql @@ -336,43 +336,41 @@ ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; ## 도시 테이블 ########################################################################### ## trade 100 이 표준 시세 -create table city ( - `city` INT(6) NOT NULL AUTO_INCREMENT, +CREATE TABLE `city` ( + `city` INT(6) NOT NULL AUTO_INCREMENT, `name` CHAR(64) NOT NULL, - level int(1) default 0, - upgrading int(1) default 0, - nation int(6) default 0, - supply int(1) default 1, - path char(32) default '', - front int(1) default 0, - pop int(7) default 50000, - pop2 int(7) default 50000, - agri int(5) default 0, - agri2 int(5) default 0, - comm int(5) default 0, - comm2 int(5) default 0, - secu int(5) default 0, - secu2 int(5) default 0, - trust float default 0, - trade int(3) default 100, - dead int(7) default 0, - def int(5) default 0, - def2 int(5) default 0, - wall int(5) default 0, - wall2 int(5) default 0, - gen1 int(4) default 0, - gen2 int(4) default 0, - gen3 int(4) default 0, - gen1set int(1) default 0, - gen2set int(1) default 0, - gen3set int(1) default 0, - state int(2) default 0, - region int(2) default 0, - term int(1) default 0, - conflict varchar(500) default '{}', - - PRIMARY KEY (city), - KEY (nation) + `level` INT(1) NOT NULL, + `upgrading` INT(1) NOT NULL DEFAULT '0', + `nation` INT(6) NOT NULL DEFAULT '0', + `supply` INT(1) NOT NULL DEFAULT '1', + `front` INT(1) NOT NULL DEFAULT '0', + `pop` INT(7) NOT NULL, + `pop2` INT(7) NOT NULL, + `agri` INT(5) NOT NULL, + `agri2` INT(5) NOT NULL, + `comm` INT(5) NOT NULL, + `comm2` INT(5) NOT NULL, + `secu` INT(5) NOT NULL, + `secu2` INT(5) NOT NULL, + `trust` FLOAT NOT NULL, + `trade` INT(3) NULL DEFAULT NULL, + `dead` INT(7) NOT NULL DEFAULT '0', + `def` INT(5) NOT NULL, + `def2` INT(5) NOT NULL, + `wall` INT(5) NOT NULL, + `wall2` INT(5) NOT NULL, + `gen1` INT(4) NOT NULL DEFAULT '0', + `gen2` INT(4) NOT NULL DEFAULT '0', + `gen3` INT(4) NOT NULL DEFAULT '0', + `gen1set` INT(1) NOT NULL DEFAULT '0', + `gen2set` INT(1) NOT NULL DEFAULT '0', + `gen3set` INT(1) NOT NULL DEFAULT '0', + `state` INT(2) NOT NULL DEFAULT '0', + `region` INT(2) NOT NULL COMMENT 'TODO:Delete', + `term` INT(1) NOT NULL DEFAULT '0', + `conflict` VARCHAR(500) NOT NULL DEFAULT '{}', + PRIMARY KEY (`city`), + INDEX `nation` (`nation`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; ########################################################################### diff --git a/src/sammo/Util.php b/src/sammo/Util.php index 25b73703..007acd8a 100644 --- a/src/sammo/Util.php +++ b/src/sammo/Util.php @@ -263,8 +263,8 @@ class Util extends \utilphp\util public static function mapWithKey($callback, $dict) { $result = []; - foreach (array_keys($dict) as $key) { - $result[$key] = ($callback)($key, $dict[$key]); + foreach ($dict as $key=>$value) { + $result[$key] = ($callback)($key, $value); } return $result; } @@ -509,6 +509,38 @@ class Util extends \utilphp\util return $sum; } + /** + * 특정 키를 가진 값으로 묶음 + * + * @param array $array 배열. 1차원 배열 또는 2차원 배열 + * @param int|string|null $key 2차원 배열에서 참조할 키. + * @return int|float 합계 + */ + public static function arrayGroupBy(array $array, $key, bool $preserveRowKey=false) { + $result = array(); + + if($preserveRowKey){ + foreach($array as $rowKey=>$val) { + if(key_exists($key, $val)){ + $result[$val[$key]][$rowKey] = $val; + }else{ + $result[""][$rowKey] = $val; + } + } + } + else{ + foreach($array as $val) { + if(key_exists($key, $val)){ + $result[$val[$key]][] = $val; + }else{ + $result[""][] = $val; + } + } + } + + return $result; + } + /** * 배열의 아무거나 고름. Python의 random.choice() *