From 50c30b7cd08c2aec06ea1c688fab31025655ed39 Mon Sep 17 00:00:00 2001 From: hide_d Date: Sun, 3 May 2020 17:30:43 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=84=EB=9E=B5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/func.php | 6 +- hwe/sammo/Command/Nation/che_급습.php | 230 +++++++++++++++++ hwe/sammo/Command/Nation/che_백성동원.php | 4 +- hwe/sammo/Command/Nation/che_수몰.php | 4 +- hwe/sammo/Command/Nation/che_이호경식.php | 231 ++++++++++++++++++ hwe/sammo/Command/Nation/che_피장파장.php | 4 + hwe/sammo/Command/Nation/che_필사즉생.php | 8 +- hwe/sammo/Command/Nation/che_허보.php | 4 +- .../Constraint/AllowDiplomacyWithTerm.php | 68 ++++++ hwe/sammo/Constraint/ConstraintHelper.php | 4 + hwe/sammo/GameConstBase.php | 4 +- 11 files changed, 554 insertions(+), 13 deletions(-) create mode 100644 hwe/sammo/Command/Nation/che_급습.php create mode 100644 hwe/sammo/Command/Nation/che_이호경식.php create mode 100644 hwe/sammo/Constraint/AllowDiplomacyWithTerm.php diff --git a/hwe/func.php b/hwe/func.php index ee33c7f4..3c021f42 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -1633,7 +1633,7 @@ function nextRuler(General $general) { //npc or npc유저인 경우 후계 찾기 if($general->getVar('npc') > 0) { $candidate = $db->queryFirstRow( - 'SELECT no,name,officer_level,IF(ABS(affinity-%i)>75,150-ABS(affinity-%i),ABS(affinity-%i)) as npcmatch2 from general where nation=%i and officer_level!=12 and npc>0 order by npcmatch2,rand() LIMIT 1', + 'SELECT no,name,officer_level,IF(ABS(affinity-%i)>75,150-ABS(affinity-%i),ABS(affinity-%i)) as npcmatch2 from general where nation=%i and officer_level!=12 and 1 <= npc and npc<=3 order by npcmatch2,rand() LIMIT 1', $general->getVar('affinity'), $general->getVar('affinity'), $general->getVar('affinity'), @@ -1642,13 +1642,13 @@ function nextRuler(General $general) { } if(!$candidate){ $candidate = $db->queryFirstRow( - 'SELECT no,name,npc,officer_level FROM general WHERE nation=%i and officer_level!= 12 AND officer_level >= 9 ORDER BY officer_level DESC LIMIT 1', + 'SELECT no,name,npc,officer_level FROM general WHERE nation=%i and officer_level!= 12 AND officer_level >= 9 and npc != 5 ORDER BY officer_level DESC LIMIT 1', $nationID ); } if(!$candidate){ $candidate = $db->queryFirstRow( - 'SELECT no,name,npc,officer_level FROM general WHERE nation=%i and officer_level!= 12 ORDER BY dedication DESC LIMIT 1', + 'SELECT no,name,npc,officer_level FROM general WHERE nation=%i and officer_level!= 12 and npc != 5 ORDER BY dedication DESC LIMIT 1', $nationID ); } diff --git a/hwe/sammo/Command/Nation/che_급습.php b/hwe/sammo/Command/Nation/che_급습.php new file mode 100644 index 00000000..f9f22e5e --- /dev/null +++ b/hwe/sammo/Command/Nation/che_급습.php @@ -0,0 +1,230 @@ +arg === null){ + return false; + } + //NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음 + if(!key_exists('destNationID', $this->arg)){ + return false; + } + $destNationID = $this->arg['destNationID']; + + if(!is_int($destNationID)){ + return false; + } + if($destNationID < 1){ + return false; + } + + $this->arg = [ + 'destNationID'=>$destNationID + ]; + return true; + } + + protected function init(){ + $general = $this->generalObj; + + $env = $this->env; + + $this->setCity(); + $this->setNation(['strategic_cmd_limit']); + + $this->setDestNation($this->arg['destNationID'], null); + + $this->runnableConstraints=[ + ConstraintHelper::OccupiedCity(), + ConstraintHelper::BeChief(), + ConstraintHelper::ExistsDestNation(), + ConstraintHelper::AllowDiplomacyWithTerm( + 1, 12, + '선포 12개월 이상인 상대국에만 가능합니다.' + ), + ConstraintHelper::AvailableStrategicCommand(), + ]; + + } + + public function getCommandDetailTitle():string{ + $name = $this->getName(); + $reqTurn = $this->getPreReqTurn()+1; + $postReqTurn = $this->getPostReqTurn(); + + return "{$name}/{$reqTurn}턴(전략$postReqTurn)"; + } + + public function getCost():array{ + return [0, 0]; + } + + public function getPreReqTurn():int{ + return 0; + } + + public function getPostReqTurn():int{ + $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); + $nextTerm = Util::round(sqrt($genCount*16)*10); + + $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); + return $nextTerm; + } + + public function getBrief():string{ + $commandName = $this->getName(); + $destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; + return "【{$destNationName}】에 {$commandName}"; + } + + + public function run():bool{ + if(!$this->isRunnable()){ + throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); + } + + $db = DB::db(); + $env = $this->env; + + $general = $this->generalObj; + $generalID = $general->getID(); + $generalName = $general->getName(); + $date = $general->getTurnTime($general::TURNTIME_HM); + + $year = $this->env['year']; + $month = $this->env['month']; + + $nation = $this->nation; + $nationID = $nation['nation']; + $nationName = $nation['name']; + + $destNation = $this->destNation; + $destNationID = $destNation['nation']; + $destNationName = $destNation['name']; + + $josaYi = JosaUtil::pick($generalName, '이'); + $josaYiNation = JosaUtil::pick($nationName, '이'); + + $commandName = $this->getName(); + $josaUl = JosaUtil::pick($commandName, '을'); + + $logger = $general->getLogger(); + $logger->pushGeneralActionLog("{$commandName} 발동! <1>$date"); + + $general->addExperience(5 * ($this->getPreReqTurn() + 1)); + $general->addDedication(5 * ($this->getPreReqTurn() + 1)); + + $broadcastMessage = "{$generalName}{$josaYi} {$destNationName}{$commandName}{$josaUl} 발동하였습니다."; + + $nationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); + foreach($nationGeneralList as $nationGeneralID){ + $nationGeneralLogger = new ActionLogger($nationGeneralID, $nationID, $year, $month); + $nationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); + $nationGeneralLogger->flush(); + } + + $josaYiCommand = JosaUtil::pick($commandName, '이'); + + $broadcastMessage = "아국에 {$commandName}{$josaYiCommand} 발동되었습니다."; + + $destNationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); + foreach($destNationGeneralList as $destNationGeneralID){ + $destNationGeneralLogger = new ActionLogger($destNationGeneralID, $destNationID, $year, $month); + $destNationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); + $destNationGeneralLogger->flush(); + } + + $destNationLogger = new ActionLogger(0, $destNationID, $year, $month); + $destNationLogger->pushNationalHistoryLog("{$nationName}{$generalName}{$josaYi} 아국에 {$commandName}{$josaUl} 발동"); + $destNationLogger->flush(); + + $logger->pushNationalHistoryLog("{$generalName}{$josaYi} {$destNationName}{$commandName}{$josaUl} 발동"); + + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); + $db->update('diplomacy', [ + 'term'=>$db->sqleval('`term` - %i', 3), + ], '(me = %i AND you = %i) OR (you = %i AND me = %i)', $nationID, $destNationID, $nationID, $destNationID); + + $general->applyDB($db); + + return true; + } + + public function getJSFiles(): array + { + return [ + 'js/defaultSelectNationByMap.js' + ]; + } + + public function getForm(): string + { + $generalObj = $this->generalObj; + $nationID = $generalObj->getNationID(); + $nationList = []; + $testTurn = new LastTurn($this->getName(), null, $this->getPreReqTurn()); + foreach(getAllNationStaticInfo() as $destNation){ + if($destNation['nation'] == $nationID){ + continue; + } + + $testTurn->setArg(['destNationID'=>$destNation['nation']]); + $testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID'=>$destNation['nation']]); + if($testCommand->isRunnable()){ + $destNation['availableCommand'] = true; + } + else{ + $destNation['availableCommand'] = false; + } + + $nationList[] = $destNation; + } + + ob_start(); +?> +
+선택된 국가에 급습을 발동합니다.
+선포, 전쟁중인 상대국에만 가능합니다.
+상대 국가를 목록에서 선택하세요.
+배경색은 현재 급습 불가능 국가는 붉은색으로 표시됩니다.
+ +pushGeneralHistoryLog('백성동원을 발동'); $logger->pushNationalHistoryLog("【전략】{$nationName}{$josaYiNation} {$destCityName}백성동원을 하였습니다."); - $db->update('nation', ['strategic_cmd_limit' => $this->getPostReqTurn()], 'nation=%i', $nationID); + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); $general->setResultTurn(new LastTurn($this->getName(), $this->arg, 0)); $general->applyDB($db); diff --git a/hwe/sammo/Command/Nation/che_수몰.php b/hwe/sammo/Command/Nation/che_수몰.php index 3907f5c5..a3a90b95 100644 --- a/hwe/sammo/Command/Nation/che_수몰.php +++ b/hwe/sammo/Command/Nation/che_수몰.php @@ -169,7 +169,9 @@ class che_수몰 extends Command\NationCommand{ $logger->pushNationalHistoryLog("{$generalName}{$josaYi} {$destCityName}수몰을 발동"); $logger->pushGlobalHistoryLog("【전략】{$nationName}{$josaYiNation} {$destCityName}수몰을 발동하였습니다."); - $db->update('nation', ['strategic_cmd_limit' => $this->getPostReqTurn()], 'nation=%i', $nationID); + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); $general->setResultTurn(new LastTurn($this->getName(), $this->arg, 0)); $general->applyDB($db); diff --git a/hwe/sammo/Command/Nation/che_이호경식.php b/hwe/sammo/Command/Nation/che_이호경식.php new file mode 100644 index 00000000..cf8bd689 --- /dev/null +++ b/hwe/sammo/Command/Nation/che_이호경식.php @@ -0,0 +1,231 @@ +arg === null){ + return false; + } + //NOTE: 멸망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 국가여도 argTest에서 바로 탈락시키지 않음 + if(!key_exists('destNationID', $this->arg)){ + return false; + } + $destNationID = $this->arg['destNationID']; + + if(!is_int($destNationID)){ + return false; + } + if($destNationID < 1){ + return false; + } + + $this->arg = [ + 'destNationID'=>$destNationID + ]; + return true; + } + + protected function init(){ + $general = $this->generalObj; + + $env = $this->env; + + $this->setCity(); + $this->setNation(['strategic_cmd_limit']); + + $this->setDestNation($this->arg['destNationID'], null); + + $this->runnableConstraints=[ + ConstraintHelper::OccupiedCity(), + ConstraintHelper::BeChief(), + ConstraintHelper::ExistsDestNation(), + ConstraintHelper::AllowDiplomacyBetweenStatus( + [0, 1], + '선포, 전쟁중인 상대국에게만 가능합니다.' + ), + ConstraintHelper::AvailableStrategicCommand(), + ]; + + } + + public function getCommandDetailTitle():string{ + $name = $this->getName(); + $reqTurn = $this->getPreReqTurn()+1; + $postReqTurn = $this->getPostReqTurn(); + + return "{$name}/{$reqTurn}턴(전략$postReqTurn)"; + } + + public function getCost():array{ + return [0, 0]; + } + + public function getPreReqTurn():int{ + return 0; + } + + public function getPostReqTurn():int{ + $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); + $nextTerm = Util::round(sqrt($genCount*16)*10); + + $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); + return $nextTerm; + } + + public function getBrief():string{ + $commandName = $this->getName(); + $destNationName = getNationStaticInfo($this->arg['destNationID'])['name']; + return "【{$destNationName}】에 {$commandName}"; + } + + + public function run():bool{ + if(!$this->isRunnable()){ + throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); + } + + $db = DB::db(); + $env = $this->env; + + $general = $this->generalObj; + $generalID = $general->getID(); + $generalName = $general->getName(); + $date = $general->getTurnTime($general::TURNTIME_HM); + + $year = $this->env['year']; + $month = $this->env['month']; + + $nation = $this->nation; + $nationID = $nation['nation']; + $nationName = $nation['name']; + + $destNation = $this->destNation; + $destNationID = $destNation['nation']; + $destNationName = $destNation['name']; + + $josaYi = JosaUtil::pick($generalName, '이'); + $josaYiNation = JosaUtil::pick($nationName, '이'); + + $commandName = $this->getName(); + $josaUl = JosaUtil::pick($commandName, '을'); + + $logger = $general->getLogger(); + $logger->pushGeneralActionLog("{$commandName} 발동! <1>$date"); + + $general->addExperience(5 * ($this->getPreReqTurn() + 1)); + $general->addDedication(5 * ($this->getPreReqTurn() + 1)); + + $broadcastMessage = "{$generalName}{$josaYi} {$destNationName}{$commandName}{$josaUl} 발동하였습니다."; + + $nationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); + foreach($nationGeneralList as $nationGeneralID){ + $nationGeneralLogger = new ActionLogger($nationGeneralID, $nationID, $year, $month); + $nationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); + $nationGeneralLogger->flush(); + } + + $josaYiCommand = JosaUtil::pick($commandName, '이'); + + $broadcastMessage = "아국에 {$commandName}{$josaYiCommand} 발동되었습니다."; + + $destNationGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); + foreach($destNationGeneralList as $destNationGeneralID){ + $destNationGeneralLogger = new ActionLogger($destNationGeneralID, $destNationID, $year, $month); + $destNationGeneralLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); + $destNationGeneralLogger->flush(); + } + + $destNationLogger = new ActionLogger(0, $destNationID, $year, $month); + $destNationLogger->pushNationalHistoryLog("{$nationName}{$generalName}{$josaYi} 아국에 {$commandName}{$josaUl} 발동"); + $destNationLogger->flush(); + + $logger->pushNationalHistoryLog("{$generalName}{$josaYi} {$destNationName}{$commandName}{$josaUl} 발동"); + + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); + $db->update('diplomacy', [ + 'term'=>$db->sqleval('IF(`state`=0, %i, `term`+ %i)', 3, 3), + 'state'=>1, + ], '(me = %i AND you = %i) OR (you = %i AND me = %i)', $nationID, $destNationID, $nationID, $destNationID); + + $general->applyDB($db); + + return true; + } + + public function getJSFiles(): array + { + return [ + 'js/defaultSelectNationByMap.js' + ]; + } + + public function getForm(): string + { + $generalObj = $this->generalObj; + $nationID = $generalObj->getNationID(); + $nationList = []; + $testTurn = new LastTurn($this->getName(), null, $this->getPreReqTurn()); + foreach(getAllNationStaticInfo() as $destNation){ + if($destNation['nation'] == $nationID){ + continue; + } + + $testTurn->setArg(['destNationID'=>$destNation['nation']]); + $testCommand = new static($generalObj, $this->env, $testTurn, ['destNationID'=>$destNation['nation']]); + if($testCommand->isRunnable()){ + $destNation['availableCommand'] = true; + } + else{ + $destNation['availableCommand'] = false; + } + + $nationList[] = $destNation; + } + + ob_start(); +?> +
+선택된 국가에 이호경식을 발동합니다.
+선포, 전쟁중인 상대국에만 가능합니다.
+상대 국가를 목록에서 선택하세요.
+배경색은 현재 이호경식 불가능 국가는 붉은색으로 표시됩니다.
+ +runnableConstraints=[ ConstraintHelper::OccupiedCity(), ConstraintHelper::BeChief(), + ConstraintHelper::ExistsDestNation(), ConstraintHelper::AllowDiplomacyBetweenStatus( [0, 1], '선포, 전쟁중인 상대국에게만 가능합니다.' @@ -167,6 +168,9 @@ class che_피장파장 extends Command\NationCommand{ $logger->pushNationalHistoryLog("{$generalName}{$josaYi} {$destNationName}{$commandName}{$josaUl} 발동"); + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); $db->update('nation', [ 'strategic_cmd_limit' => $db->sqleval('strategic_cmd_limit + %i', static::$delayCnt) ], 'nation = %i', $destNationID); diff --git a/hwe/sammo/Command/Nation/che_필사즉생.php b/hwe/sammo/Command/Nation/che_필사즉생.php index 62db26c0..f8f1c237 100644 --- a/hwe/sammo/Command/Nation/che_필사즉생.php +++ b/hwe/sammo/Command/Nation/che_필사즉생.php @@ -123,11 +123,9 @@ class che_필사즉생 extends Command\NationCommand{ $logger->pushGeneralHistoryLog('필사즉생을 발동'); $logger->pushNationalHistoryLog("{$generalName}{$josaYi} 필사즉생을 발동"); - $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); - $nextTerm = Util::round(sqrt($genCount*8)*10); - - $nextTerm = $general->onCalcStrategic($this->getName(), 'delay', $nextTerm); - $db->update('nation', ['strategic_cmd_limit' => $nextTerm], 'nation=%i', $nationID); + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); $general->setResultTurn(new LastTurn($this->getName(), $this->arg, 0)); $general->applyDB($db); diff --git a/hwe/sammo/Command/Nation/che_허보.php b/hwe/sammo/Command/Nation/che_허보.php index 5ea9653a..4a0cf8b8 100644 --- a/hwe/sammo/Command/Nation/che_허보.php +++ b/hwe/sammo/Command/Nation/che_허보.php @@ -180,7 +180,9 @@ class che_허보 extends Command\NationCommand{ $logger->pushNationalHistoryLog("{$generalName}{$josaYi} {$destCityName}허보를 발동"); $logger->pushGlobalHistoryLog("【전략】{$nationName}{$josaYiNation} {$destCityName}허보를 발동하였습니다."); - $db->update('nation', ['strategic_cmd_limit' => $this->getPostReqTurn()], 'nation=%i', $nationID); + $db->update('nation', [ + 'strategic_cmd_limit' => $this->getPostReqTurn() + ], 'nation=%i', $nationID); $general->setResultTurn(new LastTurn($this->getName(), $this->arg, 0)); $general->applyDB($db); diff --git a/hwe/sammo/Constraint/AllowDiplomacyWithTerm.php b/hwe/sammo/Constraint/AllowDiplomacyWithTerm.php new file mode 100644 index 00000000..5f6b9590 --- /dev/null +++ b/hwe/sammo/Constraint/AllowDiplomacyWithTerm.php @@ -0,0 +1,68 @@ +arg) != 3){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require allowDipCode, term, errMsg tuple"); + } + + $this->nationID = $this->nation['nation']; + $this->destNationID = $this->destNation['nation']; + [$this->allowDipCode, $this->allowMinTerm, $this->errMsg] = $this->arg; + + + if(!is_int($this->allowDipCode)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("dipCode {$this->allowDipCode} must be int"); + } + if(!is_int($this->allowMinTerm)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("term {$this->allowMinTerm} must be int"); + } + if($this->allowMinTerm < 0){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("term {$this->allowMinTerm} must be not negative"); + } + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + $db = DB::db(); + + + $valid = false; + $state = $db->queryFirstField( + 'SELECT state FROM diplomacy WHERE me = %i AND you = %i AND `state` = %i AND `term` >= %i', + $this->nationID, + $this->destNationID, + $this->allowDipCode, + $this->allowMinTerm + ); + if($state !== null){ + return true; + } + $this->reason = $this->errMsg; + return false; + } +} \ No newline at end of file diff --git a/hwe/sammo/Constraint/ConstraintHelper.php b/hwe/sammo/Constraint/ConstraintHelper.php index 1081e395..4dfc2fc6 100644 --- a/hwe/sammo/Constraint/ConstraintHelper.php +++ b/hwe/sammo/Constraint/ConstraintHelper.php @@ -15,6 +15,10 @@ class ConstraintHelper{ static function AllowDiplomacyBetweenStatus(array $allowDipCodeList, string $errMsg):array{ return [__FUNCTION__, [$allowDipCodeList, $errMsg]]; } + + static function AllowDiplomacyWithTerm(int $allowDipCode, int $allowMinTerm, string $errMsg):array{ + return [__FUNCTION__, [$allowDipCode, $allowMinTerm, $errMsg]]; + } static function AllowJoinAction():array{ return [__FUNCTION__]; diff --git a/hwe/sammo/GameConstBase.php b/hwe/sammo/GameConstBase.php index 1043479d..1eab7e0f 100644 --- a/hwe/sammo/GameConstBase.php +++ b/hwe/sammo/GameConstBase.php @@ -324,8 +324,8 @@ class GameConstBase 'che_허보', 'che_피장파장', 'che_의병모집', - //'che_이호경식', - //'che_급습', + 'che_이호경식', + 'che_급습', ], '기타'=>[ //'che_국기변경',