내부 코드 사용례에서 General 테이블의 column을 일부만 가져오는 경우가 다수 있습니다. 다만 General 클래스에서 각종 iAction에 해당하는 트리거 함수 호출을 위해서는 모든 column을 다 가져와야 정상 동작이 가능한 만큼, iAction interface를 구현한 General 클래스와, 구현하지 않은 GeneralLite 클래스 둘로 나눕니다. 또한 General 클래스에서는 필요한 column을 다 가져오도록 변경합니다. Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/236
227 lines
8.0 KiB
PHP
227 lines
8.0 KiB
PHP
<?php
|
|
|
|
namespace sammo\Event\Action;
|
|
|
|
use sammo\ActionLogger;
|
|
use sammo\CityConst;
|
|
use sammo\DB;
|
|
use sammo\Enums\GeneralQueryMode;
|
|
use sammo\Enums\InheritanceKey;
|
|
use sammo\GameConst;
|
|
use sammo\General;
|
|
use sammo\JosaUtil;
|
|
use sammo\Json;
|
|
use sammo\KVStorage;
|
|
use sammo\LiteHashDRBG;
|
|
use sammo\RandUtil;
|
|
use sammo\UniqueConst;
|
|
use sammo\Util;
|
|
|
|
use function sammo\getNationChiefLevel;
|
|
use function sammo\getNationLevel;
|
|
use function sammo\giveRandomUniqueItem;
|
|
|
|
class UpdateNationLevel extends \sammo\Event\Action
|
|
{
|
|
public function run(array $env)
|
|
{
|
|
$db = DB::db();
|
|
|
|
$year = $env['year'];
|
|
$month = $env['month'];
|
|
$startYear = $env['startyear'];
|
|
|
|
|
|
$nationCityCounts = [];
|
|
foreach ($db->queryAllLists('SELECT nation, count(*) FROM city WHERE LEVEL>=4 GROUP BY nation') as [$nationID, $cityCnt]) {
|
|
$nationCityCounts[$nationID] = $cityCnt;
|
|
}
|
|
|
|
|
|
$nationLevelByCityCnt = [
|
|
0, //방랑군
|
|
1, //호족
|
|
2, //군벌
|
|
5, //주자사
|
|
8, //주목
|
|
11, //공
|
|
16, //왕
|
|
21, //황제
|
|
];
|
|
|
|
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
|
|
//TODO: level이 진관수이소중대특 체계를 벗어날 수 있음
|
|
$nationID = $nation['nation'];
|
|
$cityCnt = $nationCityCounts[$nationID] ?? 0;
|
|
|
|
/** @var int */
|
|
$nationlevel = 0;
|
|
foreach ($nationLevelByCityCnt as $cmpNationLevel => $cmpCityCnt) {
|
|
if ($cityCnt < $cmpCityCnt) {
|
|
break;
|
|
}
|
|
$nationlevel = $cmpNationLevel;
|
|
}
|
|
|
|
if ($nationlevel > $nation['level']) {
|
|
$levelDiff = $nationlevel - $nation['level'];
|
|
$oldLevel = $nation['level'];
|
|
$nation['level'] = $nationlevel;
|
|
|
|
$updateVals = [
|
|
'level' => $nationlevel,
|
|
'gold' => $db->sqleval('gold + %i', $nationlevel * 1000),
|
|
'rice' => $db->sqleval('rice + %i', $nationlevel * 1000),
|
|
];
|
|
|
|
$nationName = $nation['name'];
|
|
$lordName = $db->queryFirstField('SELECT name FROM general WHERE nation = %i AND officer_level = 12', $nationID);
|
|
|
|
$oldNationLevelText = getNationLevel($oldLevel);
|
|
$nationLevelText = getNationLevel($nationlevel);
|
|
|
|
$logger = new ActionLogger(0, $nationID, $year, $month, false);
|
|
$josaYi = JosaUtil::pick($lordName, '이');
|
|
|
|
switch ($nationlevel) {
|
|
case 7: //황제
|
|
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
|
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><D><b>{$nationName}</b></> {$oldNationLevelText} <Y>{$lordName}</>{$josaYi} <C>{$nationLevelText}</>{$josaRo} 옹립되었습니다.");
|
|
$logger->pushNationalHistoryLog("<D><b>{$nationName}</b></> {$oldNationLevelText} <Y>{$lordName}</>{$josaYi} <C>{$nationLevelText}</>{$josaRo} 옹립");
|
|
$auxVal = Json::decode($nation['aux']);
|
|
$auxVal['can_국기변경'] = 1;
|
|
$auxVal['can_국호변경'] = 1;
|
|
$updateVals['aux'] = Json::encode($auxVal);
|
|
break;
|
|
case 6: //왕
|
|
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
|
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 책봉되었습니다.");
|
|
$logger->pushNationalHistoryLog("<D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 책봉");
|
|
break;
|
|
case 5: //공
|
|
case 4: //주목
|
|
case 3: //주자사
|
|
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
|
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 임명되었습니다.");
|
|
$logger->pushNationalHistoryLog("<D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 임명됨");
|
|
break;
|
|
case 2: //군벌
|
|
$josaRa = JosaUtil::pick($nationName, '라');
|
|
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
|
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><Y>{$lordName}</>{$josaYi} 독립하여 <D><b>{$nationName}</b></>{$josaRa}는 <C>$nationLevelText</>{$josaRo} 나섰습니다.");
|
|
$logger->pushNationalHistoryLog("<Y>{$lordName}</>{$josaYi} 독립하여 <D><b>{$nationName}</b></>{$josaRa}는 <C>$nationLevelText</>{$josaRo} 나서다");
|
|
break;
|
|
}
|
|
|
|
$db->update('nation', $updateVals, 'nation=%i', $nation['nation']);
|
|
$logger->flush();
|
|
|
|
$turnRows = [];
|
|
foreach (Util::range(getNationChiefLevel($nation['level']), 12) as $chiefLevel) {
|
|
foreach (Util::range(GameConst::$maxChiefTurn) as $turnIdx) {
|
|
$turnRows[] = [
|
|
'nation_id' => $nation['nation'],
|
|
'officer_level' => $chiefLevel,
|
|
'turn_idx' => $turnIdx,
|
|
'action' => '휴식',
|
|
'arg' => null,
|
|
'brief' => '휴식'
|
|
];
|
|
}
|
|
}
|
|
$db->insertIgnore('nation_turn', $turnRows);
|
|
|
|
if ($levelDiff) {
|
|
//유니크 아이템 하나 돌리자
|
|
$targetKillTurn = $env['killturn'];
|
|
$targetKillTurn -= 24 * 60 / $env['turnterm'];
|
|
$nationGenIDList = $db->queryFirstColumn(
|
|
'SELECT no FROM general WHERE nation = %i AND killturn >= %i AND npc < 2',
|
|
$nation['nation'],
|
|
$targetKillTurn
|
|
);
|
|
$nationGenList = General::createObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux']);
|
|
$chiefID = null;
|
|
|
|
$uniqueLotteryWeightList = [];
|
|
|
|
$relYear = $year - $startYear;
|
|
$maxTrialCountByYear = 1;
|
|
foreach (GameConst::$maxUniqueItemLimit as $tmpVals) {
|
|
[$targetYear, $targetTrialCnt] = $tmpVals;
|
|
if ($relYear < $targetYear) {
|
|
break;
|
|
}
|
|
$maxTrialCountByYear = $targetTrialCnt;
|
|
}
|
|
foreach ($nationGenList as $nationGen) {
|
|
if ($nationGen->getVar('officer_level') == 12) {
|
|
$chiefID = $nationGen->getID();
|
|
}
|
|
$trialCnt = min($maxTrialCountByYear, count(GameConst::$allItems));
|
|
|
|
foreach ($nationGen->getItems() as $item) {
|
|
if (!$item->isBuyable()) {
|
|
$trialCnt -= 1;
|
|
}
|
|
}
|
|
|
|
if ($trialCnt <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$score = $nationGen->getVar('belong') + 10;
|
|
|
|
if ($nationGen->getVar('officer_level') == 12) {
|
|
$score += 60;
|
|
} else if ($nationGen->getVar('officer_level') == 11) {
|
|
$score += 30;
|
|
} else if ($nationGen->getVar('officer_level') > 4) {
|
|
$score += 15;
|
|
}
|
|
|
|
$score *= 2 ** $trialCnt;
|
|
|
|
$uniqueLotteryWeightList[$nationGen->getID()] = [$nationGen, $score];
|
|
}
|
|
|
|
$nationLevelUpRNG = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
|
UniqueConst::$hiddenSeed,
|
|
'nationLevelUp',
|
|
$year,
|
|
$month,
|
|
$nationID
|
|
)));
|
|
|
|
foreach (Util::range($levelDiff) as $idx) {
|
|
if (!$uniqueLotteryWeightList) {
|
|
break;
|
|
}
|
|
|
|
/** @var General */
|
|
$winnerObj = $nationLevelUpRNG->choiceUsingWeightPair($uniqueLotteryWeightList);
|
|
unset($uniqueLotteryWeightList[$winnerObj->getID()]);
|
|
|
|
$givenUniqueRNG = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
|
UniqueConst::$hiddenSeed,
|
|
'givenUnique',
|
|
$year,
|
|
$month,
|
|
$nationID,
|
|
$winnerObj->getID(),
|
|
)));
|
|
giveRandomUniqueItem($givenUniqueRNG, $winnerObj, '작위보상');
|
|
$winnerObj->applyDB($db);
|
|
}
|
|
|
|
if ($chiefID) {
|
|
$chiefObj = General::createObjFromDB($chiefID);
|
|
$chiefObj->increaseInheritancePoint(InheritanceKey::unifier, 250 * $levelDiff);
|
|
$chiefObj->applyDB($db);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|