수몰 구현, createGeneralObjFromDB 최적화

This commit is contained in:
2020-03-21 17:36:36 +09:00
parent ed2bc8c390
commit b469ce0504
11 changed files with 281 additions and 35 deletions
+1 -3
View File
@@ -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) {
+1 -3
View File
@@ -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();
+1 -1
View File
@@ -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("방랑군 세력이 <G><b>{$destCityName}</b></>{$josaRo} 강행했습니다.", ActionLogger::PLAIN);
$targetLogger->flush();
-1
View File
@@ -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("방랑군 세력이 <G><b>{$destCityName}</b></>{$josaRo} 이동했습니다.", ActionLogger::PLAIN);
$targetLogger->flush();
-1
View File
@@ -62,7 +62,6 @@ class che_출병 extends Command\GeneralCommand{
ConstraintHelper::ReqGeneralRice($reqRice),
ConstraintHelper::AllowWar(),
ConstraintHelper::HasRoute(),
//ConstraintHelper::BattleGroundCity(true),
];
}
+162
View File
@@ -0,0 +1,162 @@
<?php
namespace sammo\Command\Nation;
use \sammo\{
DB, Util, JosaUtil,
General, DummyGeneral,
ActionLogger,
GameConst,
LastTurn,
GameUnitConst,
Command,
MessageTarget,
Message,
CityConst
};
use function \sammo\{
getDomesticExpLevelBonus,
CriticalRatioDomestic,
CriticalScoreEx,
GetImageURL,
function getNationStaticInfo
};
use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper;
use sammo\Event\Action;
class che_수몰 extends Command\NationCommand{
static protected $actionName = '수몰';
static public $reqArg = false;
protected function argTest():bool{
$this->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 = "<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>에 <M>수몰</>을 발동하였습니다.";
$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 = "<G><b>{$destCityName}</b></>에 <M>수몰</>이 발동되었습니다.";
$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(
"<D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} 아국의 <G><b>{$destCityName}</b></>에 <M>수몰</>을 발동", 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('<M>수몰</>을 발동');
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <D><b>{$destNationName}</b></>의 <G><b>{$destCityName}</b></>에 <M>수몰</>을 발동");
$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;
}
}
+18 -10
View File
@@ -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 = "<Y>{$generalName}</>{$josaYi} <M>필사즉생</>을 발동하였습니다.";
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);
}
@@ -0,0 +1,32 @@
<?php
namespace sammo\Constraint;
class AvailableStrategicCommand extends Constraint{
const REQ_VALUES = Constraint::REQ_NATION;
public function checkInputValues(bool $throwExeception=true):bool{
if(!parent::checkInputValues($throwExeception) && !$throwExeception){
return false;
}
if(!key_exists('strategic_cmd_limit', $this->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;
}
}
+1 -1
View File
@@ -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){
+6 -2
View File
@@ -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{
+59 -13
View File
@@ -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){