diff --git a/hwe/_admin2_submit.php b/hwe/_admin2_submit.php index 0d8fdf2d..6dc61cf8 100644 --- a/hwe/_admin2_submit.php +++ b/hwe/_admin2_submit.php @@ -32,9 +32,7 @@ $src = MessageTarget::buildQuick($session->generalID); $genObjList = []; $env = []; if($genlist){ - foreach($genlist as $genID){ - $genObjList[$genID] = General::createGeneralObjFromDB($genID); - } + $genObjList = General::createGeneralObjListFromDB($genlist); $env = $gameStor->cacheAll(); } switch($btn) { diff --git a/hwe/func_gamerule.php b/hwe/func_gamerule.php index 563dfca6..46a936da 100644 --- a/hwe/func_gamerule.php +++ b/hwe/func_gamerule.php @@ -543,9 +543,7 @@ function checkWander() { $wanderers = $db->queryFirstColumn('SELECT general.`no` FROM general LEFT JOIN nation ON general.nation = nation.nation WHERE nation.`level` = 0 AND general.`level` = 12'); - foreach($wanderers as $wandererID){ - $wanderer = General::createGeneralObjFromDB($wandererID); - + foreach(General::createGeneralObjListFromDB($wanderers) as $wanderer){ $wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin); if($wanderCmd->isRunnable()){ $logger = $wanderer->getLogger(); diff --git a/hwe/sammo/Command/General/che_강행.php b/hwe/sammo/Command/General/che_강행.php index a57e3afc..a85717da 100644 --- a/hwe/sammo/Command/General/che_강행.php +++ b/hwe/sammo/Command/General/che_강행.php @@ -138,8 +138,8 @@ class che_강행 extends Command\GeneralCommand{ 'city'=>$destCityID ], 'no IN %li and nation=%i', $generalList, $general->getNationID()); } + foreach($generalList as $targetGeneralID){ - $targetGeneral = General::createGeneralObjFromDB($targetGeneralID, [], 1); $targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $env['year'], $env['month']); $targetLogger->pushGeneralActionLog("방랑군 세력이 {$destCityName}{$josaRo} 강행했습니다.", ActionLogger::PLAIN); $targetLogger->flush(); diff --git a/hwe/sammo/Command/General/che_이동.php b/hwe/sammo/Command/General/che_이동.php index 4886751f..6e344d3f 100644 --- a/hwe/sammo/Command/General/che_이동.php +++ b/hwe/sammo/Command/General/che_이동.php @@ -138,7 +138,6 @@ class che_이동 extends Command\GeneralCommand{ ], 'no IN %li', $generalList); } foreach($generalList as $targetGeneralID){ - $targetGeneral = General::createGeneralObjFromDB($targetGeneralID, [], 1); $targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $env['year'], $env['month']); $targetLogger->pushGeneralActionLog("방랑군 세력이 {$destCityName}{$josaRo} 이동했습니다.", ActionLogger::PLAIN); $targetLogger->flush(); diff --git a/hwe/sammo/Command/General/che_출병.php b/hwe/sammo/Command/General/che_출병.php index be30fa10..77c20122 100644 --- a/hwe/sammo/Command/General/che_출병.php +++ b/hwe/sammo/Command/General/che_출병.php @@ -62,7 +62,6 @@ class che_출병 extends Command\GeneralCommand{ ConstraintHelper::ReqGeneralRice($reqRice), ConstraintHelper::AllowWar(), ConstraintHelper::HasRoute(), - //ConstraintHelper::BattleGroundCity(true), ]; } diff --git a/hwe/sammo/Command/Nation/che_수몰php b/hwe/sammo/Command/Nation/che_수몰php new file mode 100644 index 00000000..9f681401 --- /dev/null +++ b/hwe/sammo/Command/Nation/che_수몰php @@ -0,0 +1,162 @@ +arg = []; + + return true; + } + + protected function init(){ + $general = $this->generalObj; + + $env = $this->env; + + $this->setCity(); + $this->setNation(['strategic_cmd_limit']); + + $this->runnableConstraints=[ + ConstraintHelper::OccupiedCity(), + ConstraintHelper::BeChief(), + ConstraintHelper::NotNeutralDestCity(), + ConstraintHelper::NotOccupiedDestCity(), + ConstraintHelper::BattleGroundCity(), + ConstraintHelper::AvailableStrategicCommand() + ]; + } + + public function getCost():array{ + return [0, 0]; + } + + public function getPreReqTurn():int{ + return 2; + } + + public function getPostReqTurn():int{ + $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); + $nextTerm = Util::round(sqrt($genCount*8)*10); + + $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); + return $nextTerm; + } + + public function getBrief():string{ + $commandName = $this->getName(); + $destCityName = CityConst::byID($this->arg['destCityID'])->name; + $josaUl = JosaUtil::pick($destCityName, '을'); + return "【{$destCityName}】{$josaUl} {$commandName}"; + } + + public function run():bool{ + if(!$this->isRunnable()){ + throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); + } + + $db = DB::db(); + + $general = $this->generalObj; + $generalID = $general->getID(); + $generalName = $general->getName(); + $date = $general->getTurnTime($general::TURNTIME_HM); + + $year = $this->env['year']; + $month = $this->env['month']; + + $destCity = $this->destCity; + $destCityID = $destCity['city']; + $destCityName = $destCity['name']; + + $destNationID = $destCity['nation']; + $destNationName = getNationStaticInfo($destNationID)['name']; + + $nationID = $general->getNationID(); + $nationName = $this->nation['name']; + + $logger = $general->getLogger(); + $logger->pushGeneralActionLog("수몰 발동! <1>$date"); + + $general->increaseVar( + 'experience', + $general->onCalcStat($general, + 'experience', 5 * ($this->getPreReqTurn() + 1) + )); + $general->increaseVar( + 'dedication', + $general->onCalcStat($general, + 'dedication', 5 * ($this->getPreReqTurn() + 1) + )); + + $josaYi = JosaUtil::pick($generalName, '이'); + + $broadcastMessage = "{$generalName}{$josaYi} {$destCityName}수몰을 발동하였습니다."; + + $targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); + foreach($targetGeneralList as $targetGeneralID){ + $targetLogger = new ActionLogger($targetGeneralID, $nationID, $year, $month); + $targetLogger->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); + $targetLogger->flush(); + } + + $destBroadcastMessage = "{$destCityName}수몰이 발동되었습니다."; + + $targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i', $destNationID); + $destNationLogged = false; + foreach($targetGeneralList as $targetGeneralID){ + $targetLogger = new ActionLogger($targetGeneralID, $destNationID, $year, $month); + $targetLogger->pushGeneralActionLog($destBroadcastMessage, ActionLogger::PLAIN); + if(!$destNationLogged){ + $targetLogger->pushNationalHistoryLog( + "{$nationName}{$generalName}{$josaYi} 아국의 {$destCityName}수몰을 발동", ActionLogger::PLAIN + ); + $destNationLogged = true; + } + $targetLogger->flush(); + } + + $db->update('city', [ + 'def' => $db->sqleval('def * 0.2'), + 'wall' => $db->sqleval('wall * 0.2'), + ], 'city=%i', $destCityID); + + + $logger->pushGeneralHistoryLog('수몰을 발동'); + $logger->pushNationalHistoryLog("{$generalName}{$josaYi} {$destNationName}{$destCityName}수몰을 발동"); + + $db->update('nation', ['strategic_cmd_limit' => $this->getPostReqTurn()], 'nation=%i', $nationID); + + $general->setResultTurn(new LastTurn($this->getName(), $this->arg, 0)); + $general->applyDB($db); + + return true; + } +} \ No newline at end of file diff --git a/hwe/sammo/Command/Nation/che_필사즉생.php b/hwe/sammo/Command/Nation/che_필사즉생.php index 0656dd5a..18dc0851 100644 --- a/hwe/sammo/Command/Nation/che_필사즉생.php +++ b/hwe/sammo/Command/Nation/che_필사즉생.php @@ -48,7 +48,7 @@ class che_필사즉생 extends Command\NationCommand{ ConstraintHelper::AllowDiplomacyStatus($this->generalObj->getNationID(), [ 0 ], '전쟁중이 아닙니다.'), - ConstraintHelper::ReqNationValue('strategic_cmd_limit', '전략기한', '==', 0, '전략기한이 남았습니다.') + ConstraintHelper::AvailableStrategicCommand() ]; } @@ -61,7 +61,11 @@ class che_필사즉생 extends Command\NationCommand{ } public function getPostReqTurn():int{ - return 0; + $genCount = Util::valueFit($this->nation['gennum'], GameConst::$initialNationGenLimit); + $nextTerm = Util::round(sqrt($genCount*4)*10); + + $nextTerm = $this->generalObj->onCalcStrategic($this->getName(), 'delay', $nextTerm); + return $nextTerm; } public function run():bool{ @@ -82,18 +86,23 @@ class che_필사즉생 extends Command\NationCommand{ $logger = $general->getLogger(); $logger->pushGeneralActionLog("필사즉생 발동! <1>$date"); - $exp = 5 * ($this->getPreReqTurn() + 1); - $ded = 5 * ($this->getPreReqTurn() + 1); - - $exp = $general->onCalcStat($general, 'experience', $exp); - $ded = $general->onCalcStat($general, 'dedication', $ded); + $general->increaseVar( + 'experience', + $general->onCalcStat($general, + 'experience', 5 * ($this->getPreReqTurn() + 1) + )); + $general->increaseVar( + 'dedication', + $general->onCalcStat($general, + 'dedication', 5 * ($this->getPreReqTurn() + 1) + )); $josaYi = JosaUtil::pick($generalName, '이'); $broadcastMessage = "{$generalName}{$josaYi} 필사즉생을 발동하였습니다."; - foreach($db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID) as $targetGeneralID){ - $targetGeneral = General::createGeneralObjFromDB($targetGeneralID, ['train', 'atmos'], 1); + $targetGeneralList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no != %i', $nationID, $generalID); + foreach(General::createGeneralObjListFromDB($targetGeneralList, ['train', 'atmos'], 1) as $targetGeneral){ $targetGeneral->getLogger()->pushGeneralActionLog($broadcastMessage, ActionLogger::PLAIN); if($targetGeneral->getVar('train') < 100){ $targetGeneral->setVar('train', 100); @@ -102,7 +111,6 @@ class che_필사즉생 extends Command\NationCommand{ $targetGeneral->setVar('atmos', 100); } - $targetGeneral->applyDB($db); } diff --git a/hwe/sammo/Constraint/AvailableStrategicCommand.php b/hwe/sammo/Constraint/AvailableStrategicCommand.php new file mode 100644 index 00000000..f0c33eb9 --- /dev/null +++ b/hwe/sammo/Constraint/AvailableStrategicCommand.php @@ -0,0 +1,32 @@ +nation)){ + if(!$throwExeception){return false; } + throw new \InvalidArgumentException("require strategic_cmd_limit in nation"); + } + + return true; + } + + public function test():bool{ + $this->checkInputValues(); + $this->tested = true; + + if($this->nation['strategic_cmd_limit'] == 0){ + return true; + } + + $this->reason = "전략기한이 남았습니다."; + return false; + } +} \ No newline at end of file diff --git a/hwe/sammo/Constraint/BattleGroundCity.php b/hwe/sammo/Constraint/BattleGroundCity.php index ae6f0dd8..f92f2143 100644 --- a/hwe/sammo/Constraint/BattleGroundCity.php +++ b/hwe/sammo/Constraint/BattleGroundCity.php @@ -4,7 +4,7 @@ namespace sammo\Constraint; use \sammo\DB; class BattleGroundCity extends Constraint{ - const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_DEST_CITY|Constraint::REQ_BOOLEAN_ARG; + const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_DEST_CITY; public function checkInputValues(bool $throwExeception=true):bool{ if(!parent::checkInputValues($throwExeception) && !$throwExeception){ diff --git a/hwe/sammo/Constraint/ConstraintHelper.php b/hwe/sammo/Constraint/ConstraintHelper.php index d332e094..f5625fa4 100644 --- a/hwe/sammo/Constraint/ConstraintHelper.php +++ b/hwe/sammo/Constraint/ConstraintHelper.php @@ -36,8 +36,12 @@ class ConstraintHelper{ return [__FUNCTION__, $crewTypeID]; } - static function BattleGroundCity(bool $ignoreSameNation=false):array{ - return [__FUNCTION__, $ignoreSameNation]; + static function AvailableStrategicCommand():array{ + return [__FUNCTION__]; + } + + static function BattleGroundCity():array{ + return [__FUNCTION__]; } static function BeChief():array{ diff --git a/hwe/sammo/General.php b/hwe/sammo/General.php index c7a735c8..44d6255c 100644 --- a/hwe/sammo/General.php +++ b/hwe/sammo/General.php @@ -664,16 +664,7 @@ class General implements iAction{ //TODO:createGeneralObjListFromDB로, 조건으로 select query나 generalIDList가 들어가는 녀석이 필요할 수 있음 - static public function createGeneralObjFromDB(int $generalID, ?array $column=null, int $constructMode=2):self{ - $db = DB::db(); - if($constructMode > 0){ - $gameStor = KVStorage::getStorage($db, 'game_env'); - [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); - } - else{ - $year = null; - $month = null; - } + static private function mergeQueryColumn(?array $column=null, int $constructMode=2):array{ $minimumColumn = ['no', 'name', 'city', 'nation', 'level']; $defaultEventColumn = [ 'no', 'name', 'city', 'nation', 'level', @@ -692,14 +683,69 @@ class General implements iAction{ ]; if($column === null){ - $column = $fullColumn; + return $fullColumn; } else if($constructMode > 1){ - $column = array_unique(array_merge($defaultEventColumn, $column)); + return array_unique(array_merge($defaultEventColumn, $column)); } else{ - $column = array_unique(array_merge($minimumColumn, $column)); + return array_unique(array_merge($minimumColumn, $column)); } + } + + /** + * @param int[] $generalIDList + * @param null|string[] $column + * @param int $constructMode + * @return \sammo\General[] + * @throws MustNotBeReachedException + */ + static public function createGeneralObjListFromDB(array $generalIDList, ?array $column=null, int $constructMode=2):array{ + if(!$generalIDList){ + return []; + } + + $db = DB::db(); + if($constructMode > 0){ + $gameStor = KVStorage::getStorage($db, 'game_env'); + [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); + } + else{ + $year = null; + $month = null; + } + + $column = static::mergeQueryColumn($column, $constructMode); + + $rawGenerals = Util::convertArrayToDict( + $db->queryFirstRow('SELECT %l FROM general WHERE no IN %li', Util::formatListOfBackticks($column), $generalIDList), + 'no' + ); + + $result = []; + foreach($generalIDList as $generalID){ + if(!key_exists($generalID, $rawGenerals)){ + $result[$generalID] = new DummyGeneral($constructMode > 0); + continue; + } + $result[$generalID] = new static($rawGenerals[$generalID], null, $year, $month, $constructMode > 1); + } + + return $result; + } + + static public function createGeneralObjFromDB(int $generalID, ?array $column=null, int $constructMode=2):self{ + $db = DB::db(); + if($constructMode > 0){ + $gameStor = KVStorage::getStorage($db, 'game_env'); + [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); + } + else{ + $year = null; + $month = null; + } + + $column = static::mergeQueryColumn($column, $constructMode); $rawGeneral = $db->queryFirstRow('SELECT %l FROM general WHERE no = %i', Util::formatListOfBackticks($column), $generalID); if(!$rawGeneral){