diff --git a/hwe/b_myPage.php b/hwe/b_myPage.php
index 33280f78..6413b7ba 100644
--- a/hwe/b_myPage.php
+++ b/hwe/b_myPage.php
@@ -1,154 +1,161 @@
-setReadOnly();
-$userID = Session::getUserID();
-$generalID = $session->generalID;
-
-$db = DB::db();
-$gameStor = KVStorage::getStorage($db, 'game_env');
-
-increaseRefresh("내정보", 1);
-
-$me = General::createGeneralObjFromDB($generalID);
-
-$myset = $me->getVar('myset');
-if ($myset > 0) {
- $submit = 'button';
-} else {
- $submit = 'hidden';
-}
-
-$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2);
-if($gameStor->turntime <= $gameStor->opentime){
- //서버 가오픈시 할 수 있는 행동
- if($me->getNPCType() == 0){
- $showDieImmediatelyBtn = true;
- if($targetTime <= TimeUtil::now()){
- $availableDieImmediately = true;
- }
- }
-}
-
-$use_treatment = $me->getAuxVar('use_treatment')??10;
-
-?>
-
-
-
-
-
-
-=UniqueConst::$serverName?>: 내정보
-
-=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
-=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
-=WebUtil::printJS('js/common.js')?>
-=WebUtil::printJS('js/myPage.js')?>
-=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
-=WebUtil::printCSS('../d_shared/common.css')?>
-=WebUtil::printCSS('css/common.css')?>
-
-
-
-
-
-
- | =backButton()?> |
- | =banner()?> |
-
-
-
-
+setReadOnly();
+$userID = Session::getUserID();
+$generalID = $session->generalID;
+
+$db = DB::db();
+$gameStor = KVStorage::getStorage($db, 'game_env');
+$gameStor->cacheValues(['turntime', 'opentime', 'autorun_user']);
+
+increaseRefresh("내정보", 1);
+
+$me = General::createGeneralObjFromDB($generalID);
+
+$myset = $me->getVar('myset');
+if ($myset > 0) {
+ $submit = 'button';
+} else {
+ $submit = 'hidden';
+}
+
+$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2);
+if($gameStor->turntime <= $gameStor->opentime){
+ //서버 가오픈시 할 수 있는 행동
+ if($me->getNPCType() == 0){
+ $showDieImmediatelyBtn = true;
+ if($targetTime <= TimeUtil::now()){
+ $availableDieImmediately = true;
+ }
+ }
+}
+
+$use_treatment = $me->getAuxVar('use_treatment')??10;
+$use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn')??1;
+?>
+
+
+
+
+
+
+=UniqueConst::$serverName?>: 내정보
+
+=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
+=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
+=WebUtil::printJS('js/common.js')?>
+=WebUtil::printJS('js/myPage.js')?>
+=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
+=WebUtil::printCSS('../d_shared/common.css')?>
+=WebUtil::printCSS('css/common.css')?>
+
+
+
+
+
+
+ | =backButton()?> |
+ | =banner()?> |
+
+
+
+
diff --git a/hwe/j_set_my_setting.php b/hwe/j_set_my_setting.php
index cc0df838..1bec80e1 100644
--- a/hwe/j_set_my_setting.php
+++ b/hwe/j_set_my_setting.php
@@ -1,77 +1,82 @@
-setReadOnly();
-$userID = Session::getUserID();
-$generalID = $session->generalID;
-
-increaseRefresh("내정보 수정", 0);
-
-$action = Util::getPost('action');
-$tnmt = Util::getPost('tnmt', 'int', 1);
-$defence_train = Util::getPost('defence_train', 'int', 80);
-$use_treatment = Util::getPost('use_treatment', 'int', 10);
-//$detachNPC = Util::getPost('detachNPC', 'bool');
-$detachNPC = false;
-
-if ($defence_train <= 40) {
- $defence_train = 40;
-}
-
-if($defence_train <= 90){
- $defence_train = Util::round($defence_train, -1);
-}
-else{
- $defence_train = 999;
-}
-
-if($tnmt < 0 || $tnmt > 1){
- $tnmt = 1;
-}
-
-$db = DB::db();
-$me = General::createGeneralObjFromDB($generalID);
-
-
-if($defence_train != $me->getVar('defence_train')){
- if($defence_train == 999){
- $me->increaseVar('myset', -1);
- $me->setVar('defence_train', $defence_train);
- $me->increaseVar('train', -3);
- $me->increaseVar('atmos', -3);
- }
- else{
- $me->increaseVar('myset', -1);
- $me->setVar('defence_train', $defence_train);
- }
-}
-
-$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100));
-
-if($me->getVar('tnmt') != $tnmt){
- $me->setVar('tnmt', $tnmt);
-}
-
-if($me->getNPCType() == 1 && $detachNPC){
- $turnterm = $gameStor->turnterm;
-
- if($turnterm < 10){
- $targetKillTurn = 30 / $turnterm;
- }
- else{
- $targetKillTurn = 60 / $turnterm;
- }
- $me->setVar('killturn', $targetKillTurn);
-}
-
-$me->applyDB($db);
-
-Json::die([
- 'result'=>true,
- 'reason'=>'success'
+setReadOnly();
+$userID = Session::getUserID();
+$generalID = $session->generalID;
+
+increaseRefresh("내정보 수정", 0);
+
+$action = Util::getPost('action');
+$tnmt = Util::getPost('tnmt', 'int', 1);
+$defence_train = Util::getPost('defence_train', 'int', 80);
+$use_treatment = Util::getPost('use_treatment', 'int', 10);
+$use_auto_nation_turn = Util::getPost('use_auto_nation_turn', 'int', 1);
+//$detachNPC = Util::getPost('detachNPC', 'bool');
+$detachNPC = false;
+
+if ($defence_train <= 40) {
+ $defence_train = 40;
+}
+
+if($defence_train <= 90){
+ $defence_train = Util::round($defence_train, -1);
+}
+else{
+ $defence_train = 999;
+}
+
+if($tnmt < 0 || $tnmt > 1){
+ $tnmt = 1;
+}
+
+$db = DB::db();
+$me = General::createGeneralObjFromDB($generalID);
+
+
+if($defence_train != $me->getVar('defence_train')){
+ if($defence_train == 999){
+ $me->increaseVar('myset', -1);
+ $me->setVar('defence_train', $defence_train);
+ $me->increaseVar('train', -3);
+ $me->increaseVar('atmos', -3);
+ }
+ else{
+ $me->increaseVar('myset', -1);
+ $me->setVar('defence_train', $defence_train);
+ }
+}
+
+if($use_auto_nation_turn != $me->getAuxVar('use_auto_nation_turn')){
+ $me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn);
+}
+
+$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100));
+
+if($me->getVar('tnmt') != $tnmt){
+ $me->setVar('tnmt', $tnmt);
+}
+
+if($me->getNPCType() == 1 && $detachNPC){
+ $turnterm = $gameStor->turnterm;
+
+ if($turnterm < 10){
+ $targetKillTurn = 30 / $turnterm;
+ }
+ else{
+ $targetKillTurn = 60 / $turnterm;
+ }
+ $me->setVar('killturn', $targetKillTurn);
+}
+
+$me->applyDB($db);
+
+Json::die([
+ 'result'=>true,
+ 'reason'=>'success'
]);
\ No newline at end of file
diff --git a/hwe/js/myPage.js b/hwe/js/myPage.js
index 29d2160b..153c65aa 100644
--- a/hwe/js/myPage.js
+++ b/hwe/js/myPage.js
@@ -1,166 +1,167 @@
-jQuery(function($){
-
-
- var initCustomCSSForm = function(){
- var lastTimeOut = null;
- var $obj = $('#custom_css');
- var key = 'sam_customCSS';
-
- var text = localStorage.getItem(key);
- if(text){
- $obj.val(text);
- console.log(text);
- }
-
- if($obj.on('change keyup paste', function(){
- var newText = $obj.val();
- if(text == newText){
- return;
- }
- if(lastTimeOut){
- clearTimeout(lastTimeOut);
- }
- $obj.css('background-color', '#222222');
- lastTimeOut = setTimeout(function(){
- text = $obj.val();
- localStorage.setItem(key, text);
- $obj.css('background-color', 'black');
- }, 500);
- }));
-
- }
-
- $('.load_old_log').click(function(){
- var $thisBtn = $(this);
- var logType = $thisBtn.data('log_type');
- var $last = $('.log_{0}:last'.format(logType));
- var reqTo = null;
- if($last.length){
- reqTo = $last.data('seq');
- }
-
- $.post({
- url:'j_general_log_old.php',
- dataType:'json',
- data:{
- to:reqTo,
- type:logType
- }
- }).then(function(data){
- if(!data){
- return quickReject('로그를 받아오지 못했습니다.');
- }
- if(!data.result){
- return quickReject('로그를 받아오지 못했습니다. : '+data.reason);
- }
-
- var keys = Object.keys(data.log);
- if(keys.length > 1 && keys[0] < keys[1]){
- keys.reverse();
- }
-
- if(keys == 0){
- $thisBtn.hide();
- return;
- }
-
- var html = [];
- $.each(keys, function(_, key){
- if($('#log_{0}_{1}'.format(logType, key)).length){
- return true;
- }
- var item = data.log[key];
- html.push("{2}
".format(logType, key, item));
- });
-
- $('#{0}Plate'.format(logType)).append(html);
- }, errUnknown)
- .fail(function(reason){
- alert(reason);
- location.reload();
- });
- })
-
- initCustomCSSForm();
-
-
- $('#die_immediately').click(function(){
- if(!confirm('정말로 삭제하시겠습니까?')){
- return false;
- }
- $.post({
- url:'j_die_immediately.php',
- dataType:'json',
- }).then(function(data){
- if(!data){
- return quickReject('실패했습니다.');
- }
- if(!data.result){
- return quickReject(data.reason);
- }
-
- location.replace('..');
-
- }, errUnknown)
- .fail(function(reason){
- alert(reason);
- location.reload();
- });
- return false;
- return false;
- });
-
- $('#vacation').click(function(){
- if(!confirm('휴가 기능을 신청할까요?')){
- return false;
- }
- $.post({
- url:'j_vacation.php',
- dataType:'json',
- }).then(function(data){
- if(!data){
- return quickReject('실패했습니다.');
- }
- if(!data.result){
- return quickReject(data.reason);
- }
-
- location.reload();
-
- }, errUnknown)
- .fail(function(reason){
- alert(reason);
- location.reload();
- });
- return false;
- return false;
- });
-
- $('#set_my_setting').click(function(){
- $.post({
- url:'j_set_my_setting.php',
- dataType:'json',
- data:{
- tnmt:$('.tnmt:checked').val(),
- defence_train:$('#defence_train').val(),
- use_treatment:$('#use_treatment').val(),
- }
- }).then(function(data){
- if(!data){
- return quickReject('실패했습니다.');
- }
- if(!data.result){
- return quickReject(data.reason);
- }
-
- location.reload();
-
- }, errUnknown)
- .fail(function(reason){
- alert(reason);
- location.reload();
- });
- return false;
- return false;
- });
+jQuery(function($) {
+
+
+ var initCustomCSSForm = function() {
+ var lastTimeOut = null;
+ var $obj = $('#custom_css');
+ var key = 'sam_customCSS';
+
+ var text = localStorage.getItem(key);
+ if (text) {
+ $obj.val(text);
+ console.log(text);
+ }
+
+ if ($obj.on('change keyup paste', function() {
+ var newText = $obj.val();
+ if (text == newText) {
+ return;
+ }
+ if (lastTimeOut) {
+ clearTimeout(lastTimeOut);
+ }
+ $obj.css('background-color', '#222222');
+ lastTimeOut = setTimeout(function() {
+ text = $obj.val();
+ localStorage.setItem(key, text);
+ $obj.css('background-color', 'black');
+ }, 500);
+ }));
+
+ }
+
+ $('.load_old_log').click(function() {
+ var $thisBtn = $(this);
+ var logType = $thisBtn.data('log_type');
+ var $last = $('.log_{0}:last'.format(logType));
+ var reqTo = null;
+ if ($last.length) {
+ reqTo = $last.data('seq');
+ }
+
+ $.post({
+ url: 'j_general_log_old.php',
+ dataType: 'json',
+ data: {
+ to: reqTo,
+ type: logType
+ }
+ }).then(function(data) {
+ if (!data) {
+ return quickReject('로그를 받아오지 못했습니다.');
+ }
+ if (!data.result) {
+ return quickReject('로그를 받아오지 못했습니다. : ' + data.reason);
+ }
+
+ var keys = Object.keys(data.log);
+ if (keys.length > 1 && keys[0] < keys[1]) {
+ keys.reverse();
+ }
+
+ if (keys == 0) {
+ $thisBtn.hide();
+ return;
+ }
+
+ var html = [];
+ $.each(keys, function(_, key) {
+ if ($('#log_{0}_{1}'.format(logType, key)).length) {
+ return true;
+ }
+ var item = data.log[key];
+ html.push("{2}
".format(logType, key, item));
+ });
+
+ $('#{0}Plate'.format(logType)).append(html);
+ }, errUnknown)
+ .fail(function(reason) {
+ alert(reason);
+ location.reload();
+ });
+ })
+
+ initCustomCSSForm();
+
+
+ $('#die_immediately').click(function() {
+ if (!confirm('정말로 삭제하시겠습니까?')) {
+ return false;
+ }
+ $.post({
+ url: 'j_die_immediately.php',
+ dataType: 'json',
+ }).then(function(data) {
+ if (!data) {
+ return quickReject('실패했습니다.');
+ }
+ if (!data.result) {
+ return quickReject(data.reason);
+ }
+
+ location.replace('..');
+
+ }, errUnknown)
+ .fail(function(reason) {
+ alert(reason);
+ location.reload();
+ });
+ return false;
+ return false;
+ });
+
+ $('#vacation').click(function() {
+ if (!confirm('휴가 기능을 신청할까요?')) {
+ return false;
+ }
+ $.post({
+ url: 'j_vacation.php',
+ dataType: 'json',
+ }).then(function(data) {
+ if (!data) {
+ return quickReject('실패했습니다.');
+ }
+ if (!data.result) {
+ return quickReject(data.reason);
+ }
+
+ location.reload();
+
+ }, errUnknown)
+ .fail(function(reason) {
+ alert(reason);
+ location.reload();
+ });
+ return false;
+ return false;
+ });
+
+ $('#set_my_setting').click(function() {
+ $.post({
+ url: 'j_set_my_setting.php',
+ dataType: 'json',
+ data: {
+ tnmt: $('.tnmt:checked').val(),
+ defence_train: $('#defence_train').val(),
+ use_treatment: $('#use_treatment').val(),
+ use_auto_nation_turn: $('#use_auto_nation_turn').val(),
+ }
+ }).then(function(data) {
+ if (!data) {
+ return quickReject('실패했습니다.');
+ }
+ if (!data.result) {
+ return quickReject(data.reason);
+ }
+
+ location.reload();
+
+ }, errUnknown)
+ .fail(function(reason) {
+ alert(reason);
+ location.reload();
+ });
+ return false;
+ return false;
+ });
});
\ No newline at end of file
diff --git a/hwe/sammo/GeneralAI.php b/hwe/sammo/GeneralAI.php
index f74512a6..eb2ed702 100644
--- a/hwe/sammo/GeneralAI.php
+++ b/hwe/sammo/GeneralAI.php
@@ -3251,6 +3251,9 @@ class GeneralAI
$month = $this->env['month'];
if($npcType >= 2){
+ if(!($general->getAuxVar('use_auto_nation_turn')??1)){
+ $general->setAuxVar('use_auto_nation_turn', 1);
+ }
if($general->getVar('officer_level') == 12){
if (in_array($month, [3, 6, 9, 12])) {
$this->choosePromotion();
diff --git a/hwe/sammo/TurnExecutionHelper.php b/hwe/sammo/TurnExecutionHelper.php
index b6532979..f5680d9d 100644
--- a/hwe/sammo/TurnExecutionHelper.php
+++ b/hwe/sammo/TurnExecutionHelper.php
@@ -1,445 +1,445 @@
-generalObj = $general;
- }
-
- public function __destruct()
- {
- $this->applyDB();
- }
-
- public function applyDB(){
- $db = DB::db();
- $this->generalObj->applyDB($db);
- }
-
- public function getGeneral():General{
- return $this->generalObj;
- }
-
- public function preprocessCommand(array $env){
- $general = $this->getGeneral();
- $caller = $general->getPreTurnExecuteTriggerList($general);
- $caller->merge(new GeneralTriggerCaller(
- new GeneralTrigger\che_부상경감($general),
- new GeneralTrigger\che_병력군량소모($general)
- ));
-
- $caller->fire($env);
- }
-
- public function processBlocked():bool{
- $general = $this->getGeneral();
-
- $blocked = $general->getVar('block');
- if($blocked < 2){
- return false;
- }
-
- $date = $general->getTurnTime($general::TURNTIME_HM);
- $logger = $general->getLogger();
- if($blocked == 2){
- $general->increaseVarWithLimit('killturn', -1, 0);
- $logger->pushGeneralActionLog("현재 멀티, 또는 비매너로 인한블럭> 대상자입니다. <1>$date>");
- }
- else if($blocked == 3){
- $general->increaseVarWithLimit('killturn', -1, 0);
- $logger->pushGeneralActionLog("현재 악성유저로 분류되어 블럭> 대상자입니다. <1>$date>");
- }
- else{
- //Hmm?
- return false;
- }
-
- return true;
- }
-
- public function processNationCommand(Command\NationCommand $commandObj):LastTurn{
- $general = $this->getGeneral();
-
- while(true){
- if(!$commandObj->hasFullConditionMet()){
- $date = $general->getTurnTime($general::TURNTIME_HM);
- $failString = $commandObj->getFailString();
- $text = "{$failString} <1>{$date}>";
- $general->getLogger()->pushGeneralActionLog($text);
- break;
- }
-
- if(!$commandObj->addTermStack()){
- $date = $general->getTurnTime($general::TURNTIME_HM);
- $termString = $commandObj->getTermString();
- $text = "{$termString} <1>{$date}>";
- $general->getLogger()->pushGeneralActionLog($text);
- break;
- }
-
- $result = $commandObj->run();
- if($result){
- break;
- }
-
-
- $alt = $commandObj->getAlternativeCommand();
- if($alt === null){
- break;
- }
- $commandObj = $alt;
- $commandClassName = $alt->getName();
- }
-
- return $commandObj->getResultTurn();
- }
-
- public function processCommand(Command\GeneralCommand $commandObj, bool $autorunMode){
-
- $general = $this->getGeneral();
-
- $db = DB::db();
- $gameStor = KVStorage::getStorage($db, 'game_env');
- $commandClassName = $commandObj->getName();
-
- while(true){
- if(!$commandObj->hasFullConditionMet()){
- $date = $general->getTurnTime($general::TURNTIME_HM);
- $failString = $commandObj->getFailString();
- $text = "{$failString} <1>{$date}>";
- $general->getLogger()->pushGeneralActionLog($text);
- break;
- }
-
- if(!$commandObj->addTermStack()){
- $date = $general->getTurnTime($general::TURNTIME_HM);
- $termString = $commandObj->getTermString();
- $text = "{$termString} <1>{$date}>";
- $general->getLogger()->pushGeneralActionLog($text);
- break;
- }
-
- $result = $commandObj->run();
- if($result){
- break;
- }
- $alt = $commandObj->getAlternativeCommand();
- if($alt === null){
- break;
- }
- $commandObj = $alt;
- $commandClassName = $alt->getName();
- }
-
-
- $general->clearActivatedSkill();
-
- $killTurn = $gameStor->killturn;
-
- if($general->getNPCType() >= 2){
- $general->increaseVarWithLimit('killturn', -1);
- }
- else if($general->getVar('killturn') > $killTurn){
- $general->increaseVarWithLimit('killturn', -1);
- }
- else if($autorunMode){
- $general->increaseVarWithLimit('killturn', -1);
- }
- else if($commandClassName == '휴식'){
- $general->increaseVarWithLimit('killturn', -1);
- }
- else{
- $general->setVar('killturn', $killTurn);
- }
-
- return $commandObj->getResultTurn();
- }
-
- function updateTurnTime(){
- $db = DB::db();
- $gameStor = KVStorage::getStorage($db, 'game_env');
-
- $general = $this->getGeneral();
- $generalID = $general->getID();
- $logger = $general->getLogger();
- $general->setVar('con', 0);
-
- $generalName = $general->getName();
-
- // 삭턴장수 삭제처리
- if($general->getVar('killturn') <= 0){
- // npc유저 삭턴시 npc로 전환
- if($general->getNPCType() == 1 && $general->getVar('deadyear') > $gameStor->year){
-
- $ownerName = $general->getVar('owner_name');
- $josaYi = JosaUtil::pick($ownerName, '이');
-
- $logger->pushGlobalActionLog("{$ownerName}>{$josaYi} {$generalName}>의 육체에서 유체이탈>합니다!");
-
- $general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12);
- $general->setVar('npc', $general->getVar('npc_org'));
- $general->setVar('owner', 1);
- $general->setVar('defence_train', 80);
- $general->setVar('owner_name', null);
- }
- else{
- $general->applyDB($db);
- storeOldGeneral($generalID, $gameStor->year, $gameStor->month);
- $general->kill($db);
- return;
- }
- }
-
- //은퇴
- if($general->getVar('age') >= GameConst::$retirementYear && $general->getNPCType() == 0) {
- if($gameStor->isunited == 0) {
- $general->applyDB($db);
- CheckHall($generalID);
- }
-
- $general->rebirth();
- }
-
- $turntime = addTurn($general->getTurnTime(), $gameStor->turnterm);
- $general->setVar('turntime', $turntime);
-
- }
-
-
- static public function executeGeneralCommandUntil(string $date, \DateTimeInterface $limitActionTime, int $year, int $month){
- $db = DB::db();
- $generalsTodo = $db->query(
- 'SELECT no,name,turntime,killturn,block,npc,deadyear FROM general WHERE turntime < %s ORDER BY turntime ASC, `no` ASC',
- $date
- );
-
- $currentTurn = null;
-
- $gameStor = KVStorage::getStorage($db, 'game_env');
- $autorun_user = $gameStor->autorun_user;
-
- foreach($generalsTodo as $rawGeneral){
- $currActionTime = new \DateTimeImmutable();
- if($currActionTime > $limitActionTime){
- return [true, $currentTurn];
- }
-
- $general = General::createGeneralObjFromDB($rawGeneral['no']);
- $turnObj = new static($general);
-
- $env = $gameStor->getAll(true);
-
- $hasNationTurn = false;
- if($general->getVar('nation') != 0 && $general->getVar('officer_level') >= 5){
- $nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env');
- $lastNationTurnKey = "turn_last_{$general->getVar('officer_level')}";
- //수뇌 몇 없는데 매번 left join 하는건 낭비인것 같다.
- $rawNationTurn = $db->queryFirstRow(
- 'SELECT action, arg FROM nation_turn WHERE nation_id = %i AND officer_level = %i AND turn_idx =0',
- $general->getVar('nation'),
- $general->getVar('officer_level')
- )??[];
- $hasNationTurn = true;
- $nationCommand = $rawNationTurn['action']??null;
- $nationArg = Json::decode($rawNationTurn['arg']??null);
- $lastNationTurn = LastTurn::fromRaw($nationStor->getValue($lastNationTurnKey));
- $nationCommandObj = buildNationCommandClass($nationCommand, $general, $env, $lastNationTurn, $nationArg);
- }
-
- $autorunMode = false;
- $ai = null;
-
- $turnObj->preprocessCommand($env);
- $generalCommandObj = $general->getReservedTurn(0, $env);
-
- if($general->getNPCType() >= 2 || ($autorun_user['limit_minutes']??false)){
- $ai = new GeneralAI($turnObj->getGeneral());
- }
-
- if(!$turnObj->processBlocked()){
-
- if($hasNationTurn){
- if($ai){
- $nationCommandObj = $ai->chooseNationTurn($nationCommandObj);
- $cityName = CityConst::byID($general->getCityID())->name;
- LogText("NationTurn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$nationCommandObj->getBrief()}, {$nationCommandObj->reason}, ");
- }
- $resultNationTurn = $turnObj->processNationCommand(
- $nationCommandObj
- );
- $nationStor->setValue($lastNationTurnKey, $resultNationTurn->toRaw());
- }
-
- if($ai){
- $newGeneralCommandObj = $ai->chooseGeneralTurn($generalCommandObj); // npc AI 처리
- if($generalCommandObj !== $newGeneralCommandObj){
- $autorunMode = true;
- $generalCommandObj = $newGeneralCommandObj;
- }
- $cityName = CityConst::byID($general->getCityID())->name;
- LogText("turn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$generalCommandObj->getBrief()}, {$generalCommandObj->reason}, ");
- }
-
- $turnObj->processCommand($generalCommandObj, $autorunMode);
- }
- pullNationCommand($general->getVar('nation'), $general->getVar('officer_level'));
- pullGeneralCommand($general->getID());
-
- $currentTurn = $general->getTurnTime();
- $general->increaseVarWithLimit('myset', 3, null, 9);
-
- $turnObj->updateTurnTime();
- $turnObj->applyDB();
-
-
- }
-
- return [false, $currentTurn];
- }
-
- static public function executeAllCommand(){
- //if(!timeover()) { return; }
-
- $db = DB::db();
-
- $gameStor = KVStorage::getStorage($db, 'game_env');
-
- if(TimeUtil::now(true) < $gameStor->turntime){
- //턴 시각 이전이면 아무것도 하지 않음
- return true;
- }
-
- if(!tryLock()){
- return;
- }
-
- if ($gameStor->isunited == 2) {
- //천통시에는 동결
- return;
- }
-
- $gameStor->cacheAll();
- // 1턴이상 갱신 없었으면 서버 지연
- checkDelay();
- // 접속자수, 접속국가, 국가별 접속장수 갱신
- updateOnline();
- //접속자 수 따라서 갱신제한 변경
- CheckOverhead();
-
- $date = TimeUtil::now(true);
- // 최종 처리 월턴의 다음 월턴시간 구함
- $prevTurn = cutTurn($gameStor->turntime, $gameStor->turnterm);
- $nextTurn = addTurn($prevTurn, $gameStor->turnterm);
-
- $maxActionTime = Util::toInt(ini_get('max_execution_time'));
- if($maxActionTime == 0){
- $maxActionTime = 60;
- }
- else {
- $maxActionTime = max($maxActionTime * 2 / 3, $maxActionTime - 10);
- }
-
- $limitActionTime = (new \DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($maxActionTime));
-
- // 현재 턴 이전 월턴까지 모두처리.
- //최종 처리 이후 다음 월턴이 현재 시간보다 전이라면
- while ($nextTurn <= $date) {
-
- [$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
- $nextTurn, $limitActionTime, $gameStor->year, $gameStor->month
- );
-
- // 트래픽 업데이트
- updateTraffic();
-
- if($executionOver){
- if($currentTurn !== null){
- $gameStor->turntime = $currentTurn;
- }
- unlock();
- return;
- }
-
-
- // 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모
- if(!preUpdateMonthly()){
- $gameStor->resetCache(true);
- unlock();
- throw new \RuntimeException('preUpdateMonthly() 처리 에러');
- }
-
- turnDate($nextTurn);
-
- $logger = new ActionLogger(0, 0, $gameStor->year, $gameStor->month, false);
-
- // 분기계산. 장수들 턴보다 먼저 있다면 먼저처리
- if($gameStor->month == 1) {
- processGoldIncome();
- processSpring();
- updateYearly();
- updateQuaterly();
- disaster();
- tradeRate();
- addAge();
- // 새해 알림
- $logger->pushGlobalActionLog("{$gameStor->year}>년이 되었습니다.");
- $logger->flush(); //TODO: globalAction류는 전역에서 관리하는것이 좋을 듯.
- } elseif($gameStor->month == 4) {
- updateQuaterly();
- disaster();
- } elseif($gameStor->month == 7) {
- processRiceIncome();
- processFall();
- updateQuaterly();
- disaster();
- tradeRate();
- } elseif($gameStor->month == 10) {
- updateQuaterly();
- disaster();
- }
-
- // 이벤트 핸들러 동작
- foreach (DB::db()->query('SELECT * from event') as $rawEvent) {
- $eventID = $rawEvent['id'];
- $cond = Json::decode($rawEvent['condition']);
- $action = Json::decode($rawEvent['action']);
- $event = new Event\EventHandler($cond, $action);
-
- $event->tryRunEvent(['currentEventID'=>$eventID] + $gameStor->getAll(true));
- }
-
- postUpdateMonthly();
-
- // 다음달로 넘김
- $prevTurn = $nextTurn;
- $nextTurn = addTurn($prevTurn, $gameStor->turnterm);
- $gameStor->turntime = $prevTurn;
- }
-
- // 그 시각 년도,월 저장
- turnDate($prevTurn);
- // 현재시간의 월턴시간 이후 분단위 장수 처리
-
- [$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
- $date, $limitActionTime, $gameStor->year, $gameStor->month
- );
-
- if($currentTurn !== null){
- $gameStor->turntime = $currentTurn;
- }
-
- //토너먼트 처리
- processTournament();
- //거래 처리
- processAuction();
- // 잡금 해제
- $gameStor->resetCache(true);
- unlock();
- }
+generalObj = $general;
+ }
+
+ public function __destruct()
+ {
+ $this->applyDB();
+ }
+
+ public function applyDB(){
+ $db = DB::db();
+ $this->generalObj->applyDB($db);
+ }
+
+ public function getGeneral():General{
+ return $this->generalObj;
+ }
+
+ public function preprocessCommand(array $env){
+ $general = $this->getGeneral();
+ $caller = $general->getPreTurnExecuteTriggerList($general);
+ $caller->merge(new GeneralTriggerCaller(
+ new GeneralTrigger\che_부상경감($general),
+ new GeneralTrigger\che_병력군량소모($general)
+ ));
+
+ $caller->fire($env);
+ }
+
+ public function processBlocked():bool{
+ $general = $this->getGeneral();
+
+ $blocked = $general->getVar('block');
+ if($blocked < 2){
+ return false;
+ }
+
+ $date = $general->getTurnTime($general::TURNTIME_HM);
+ $logger = $general->getLogger();
+ if($blocked == 2){
+ $general->increaseVarWithLimit('killturn', -1, 0);
+ $logger->pushGeneralActionLog("현재 멀티, 또는 비매너로 인한블럭> 대상자입니다. <1>$date>");
+ }
+ else if($blocked == 3){
+ $general->increaseVarWithLimit('killturn', -1, 0);
+ $logger->pushGeneralActionLog("현재 악성유저로 분류되어 블럭> 대상자입니다. <1>$date>");
+ }
+ else{
+ //Hmm?
+ return false;
+ }
+
+ return true;
+ }
+
+ public function processNationCommand(Command\NationCommand $commandObj):LastTurn{
+ $general = $this->getGeneral();
+
+ while(true){
+ if(!$commandObj->hasFullConditionMet()){
+ $date = $general->getTurnTime($general::TURNTIME_HM);
+ $failString = $commandObj->getFailString();
+ $text = "{$failString} <1>{$date}>";
+ $general->getLogger()->pushGeneralActionLog($text);
+ break;
+ }
+
+ if(!$commandObj->addTermStack()){
+ $date = $general->getTurnTime($general::TURNTIME_HM);
+ $termString = $commandObj->getTermString();
+ $text = "{$termString} <1>{$date}>";
+ $general->getLogger()->pushGeneralActionLog($text);
+ break;
+ }
+
+ $result = $commandObj->run();
+ if($result){
+ break;
+ }
+
+
+ $alt = $commandObj->getAlternativeCommand();
+ if($alt === null){
+ break;
+ }
+ $commandObj = $alt;
+ $commandClassName = $alt->getName();
+ }
+
+ return $commandObj->getResultTurn();
+ }
+
+ public function processCommand(Command\GeneralCommand $commandObj, bool $autorunMode){
+
+ $general = $this->getGeneral();
+
+ $db = DB::db();
+ $gameStor = KVStorage::getStorage($db, 'game_env');
+ $commandClassName = $commandObj->getName();
+
+ while(true){
+ if(!$commandObj->hasFullConditionMet()){
+ $date = $general->getTurnTime($general::TURNTIME_HM);
+ $failString = $commandObj->getFailString();
+ $text = "{$failString} <1>{$date}>";
+ $general->getLogger()->pushGeneralActionLog($text);
+ break;
+ }
+
+ if(!$commandObj->addTermStack()){
+ $date = $general->getTurnTime($general::TURNTIME_HM);
+ $termString = $commandObj->getTermString();
+ $text = "{$termString} <1>{$date}>";
+ $general->getLogger()->pushGeneralActionLog($text);
+ break;
+ }
+
+ $result = $commandObj->run();
+ if($result){
+ break;
+ }
+ $alt = $commandObj->getAlternativeCommand();
+ if($alt === null){
+ break;
+ }
+ $commandObj = $alt;
+ $commandClassName = $alt->getName();
+ }
+
+
+ $general->clearActivatedSkill();
+
+ $killTurn = $gameStor->killturn;
+
+ if($general->getNPCType() >= 2){
+ $general->increaseVarWithLimit('killturn', -1);
+ }
+ else if($general->getVar('killturn') > $killTurn){
+ $general->increaseVarWithLimit('killturn', -1);
+ }
+ else if($autorunMode){
+ $general->increaseVarWithLimit('killturn', -1);
+ }
+ else if($commandClassName == '휴식'){
+ $general->increaseVarWithLimit('killturn', -1);
+ }
+ else{
+ $general->setVar('killturn', $killTurn);
+ }
+
+ return $commandObj->getResultTurn();
+ }
+
+ function updateTurnTime(){
+ $db = DB::db();
+ $gameStor = KVStorage::getStorage($db, 'game_env');
+
+ $general = $this->getGeneral();
+ $generalID = $general->getID();
+ $logger = $general->getLogger();
+ $general->setVar('con', 0);
+
+ $generalName = $general->getName();
+
+ // 삭턴장수 삭제처리
+ if($general->getVar('killturn') <= 0){
+ // npc유저 삭턴시 npc로 전환
+ if($general->getNPCType() == 1 && $general->getVar('deadyear') > $gameStor->year){
+
+ $ownerName = $general->getVar('owner_name');
+ $josaYi = JosaUtil::pick($ownerName, '이');
+
+ $logger->pushGlobalActionLog("{$ownerName}>{$josaYi} {$generalName}>의 육체에서 유체이탈>합니다!");
+
+ $general->setVar('killturn', ($general->getVar('deadyear') - $gameStor->year) * 12);
+ $general->setVar('npc', $general->getVar('npc_org'));
+ $general->setVar('owner', 1);
+ $general->setVar('defence_train', 80);
+ $general->setVar('owner_name', null);
+ }
+ else{
+ $general->applyDB($db);
+ storeOldGeneral($generalID, $gameStor->year, $gameStor->month);
+ $general->kill($db);
+ return;
+ }
+ }
+
+ //은퇴
+ if($general->getVar('age') >= GameConst::$retirementYear && $general->getNPCType() == 0) {
+ if($gameStor->isunited == 0) {
+ $general->applyDB($db);
+ CheckHall($generalID);
+ }
+
+ $general->rebirth();
+ }
+
+ $turntime = addTurn($general->getTurnTime(), $gameStor->turnterm);
+ $general->setVar('turntime', $turntime);
+
+ }
+
+
+ static public function executeGeneralCommandUntil(string $date, \DateTimeInterface $limitActionTime, int $year, int $month){
+ $db = DB::db();
+ $generalsTodo = $db->query(
+ 'SELECT no,name,turntime,killturn,block,npc,deadyear FROM general WHERE turntime < %s ORDER BY turntime ASC, `no` ASC',
+ $date
+ );
+
+ $currentTurn = null;
+
+ $gameStor = KVStorage::getStorage($db, 'game_env');
+ $autorun_user = $gameStor->autorun_user;
+
+ foreach($generalsTodo as $rawGeneral){
+ $currActionTime = new \DateTimeImmutable();
+ if($currActionTime > $limitActionTime){
+ return [true, $currentTurn];
+ }
+
+ $general = General::createGeneralObjFromDB($rawGeneral['no']);
+ $turnObj = new static($general);
+
+ $env = $gameStor->getAll(true);
+
+ $hasNationTurn = false;
+ if($general->getVar('nation') != 0 && $general->getVar('officer_level') >= 5){
+ $nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env');
+ $lastNationTurnKey = "turn_last_{$general->getVar('officer_level')}";
+ //수뇌 몇 없는데 매번 left join 하는건 낭비인것 같다.
+ $rawNationTurn = $db->queryFirstRow(
+ 'SELECT action, arg FROM nation_turn WHERE nation_id = %i AND officer_level = %i AND turn_idx =0',
+ $general->getVar('nation'),
+ $general->getVar('officer_level')
+ )??[];
+ $hasNationTurn = true;
+ $nationCommand = $rawNationTurn['action']??null;
+ $nationArg = Json::decode($rawNationTurn['arg']??null);
+ $lastNationTurn = LastTurn::fromRaw($nationStor->getValue($lastNationTurnKey));
+ $nationCommandObj = buildNationCommandClass($nationCommand, $general, $env, $lastNationTurn, $nationArg);
+ }
+
+ $autorunMode = false;
+ $ai = null;
+
+ $turnObj->preprocessCommand($env);
+ $generalCommandObj = $general->getReservedTurn(0, $env);
+
+ if($general->getNPCType() >= 2 || ($autorun_user['limit_minutes']??false)){
+ $ai = new GeneralAI($turnObj->getGeneral());
+ }
+
+ if(!$turnObj->processBlocked()){
+
+ if($hasNationTurn){
+ if($ai && ($general->getAuxVar('use_auto_nation_turn')??1)){
+ $nationCommandObj = $ai->chooseNationTurn($nationCommandObj);
+ $cityName = CityConst::byID($general->getCityID())->name;
+ LogText("NationTurn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$nationCommandObj->getBrief()}, {$nationCommandObj->reason}, ");
+ }
+ $resultNationTurn = $turnObj->processNationCommand(
+ $nationCommandObj
+ );
+ $nationStor->setValue($lastNationTurnKey, $resultNationTurn->toRaw());
+ }
+
+ if($ai){
+ $newGeneralCommandObj = $ai->chooseGeneralTurn($generalCommandObj); // npc AI 처리
+ if($generalCommandObj !== $newGeneralCommandObj){
+ $autorunMode = true;
+ $generalCommandObj = $newGeneralCommandObj;
+ }
+ $cityName = CityConst::byID($general->getCityID())->name;
+ LogText("turn", "General, {$general->getName()}, {$general->getID()}, {$cityName}, {$general->getStaticNation()['name']}, {$generalCommandObj->getBrief()}, {$generalCommandObj->reason}, ");
+ }
+
+ $turnObj->processCommand($generalCommandObj, $autorunMode);
+ }
+ pullNationCommand($general->getVar('nation'), $general->getVar('officer_level'));
+ pullGeneralCommand($general->getID());
+
+ $currentTurn = $general->getTurnTime();
+ $general->increaseVarWithLimit('myset', 3, null, 9);
+
+ $turnObj->updateTurnTime();
+ $turnObj->applyDB();
+
+
+ }
+
+ return [false, $currentTurn];
+ }
+
+ static public function executeAllCommand(){
+ //if(!timeover()) { return; }
+
+ $db = DB::db();
+
+ $gameStor = KVStorage::getStorage($db, 'game_env');
+
+ if(TimeUtil::now(true) < $gameStor->turntime){
+ //턴 시각 이전이면 아무것도 하지 않음
+ return true;
+ }
+
+ if(!tryLock()){
+ return;
+ }
+
+ if ($gameStor->isunited == 2) {
+ //천통시에는 동결
+ return;
+ }
+
+ $gameStor->cacheAll();
+ // 1턴이상 갱신 없었으면 서버 지연
+ checkDelay();
+ // 접속자수, 접속국가, 국가별 접속장수 갱신
+ updateOnline();
+ //접속자 수 따라서 갱신제한 변경
+ CheckOverhead();
+
+ $date = TimeUtil::now(true);
+ // 최종 처리 월턴의 다음 월턴시간 구함
+ $prevTurn = cutTurn($gameStor->turntime, $gameStor->turnterm);
+ $nextTurn = addTurn($prevTurn, $gameStor->turnterm);
+
+ $maxActionTime = Util::toInt(ini_get('max_execution_time'));
+ if($maxActionTime == 0){
+ $maxActionTime = 60;
+ }
+ else {
+ $maxActionTime = max($maxActionTime * 2 / 3, $maxActionTime - 10);
+ }
+
+ $limitActionTime = (new \DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($maxActionTime));
+
+ // 현재 턴 이전 월턴까지 모두처리.
+ //최종 처리 이후 다음 월턴이 현재 시간보다 전이라면
+ while ($nextTurn <= $date) {
+
+ [$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
+ $nextTurn, $limitActionTime, $gameStor->year, $gameStor->month
+ );
+
+ // 트래픽 업데이트
+ updateTraffic();
+
+ if($executionOver){
+ if($currentTurn !== null){
+ $gameStor->turntime = $currentTurn;
+ }
+ unlock();
+ return;
+ }
+
+
+ // 1달마다 처리하는 것들, 벌점 감소 및 건국,전턴,합병 -1, 군량 소모
+ if(!preUpdateMonthly()){
+ $gameStor->resetCache(true);
+ unlock();
+ throw new \RuntimeException('preUpdateMonthly() 처리 에러');
+ }
+
+ turnDate($nextTurn);
+
+ $logger = new ActionLogger(0, 0, $gameStor->year, $gameStor->month, false);
+
+ // 분기계산. 장수들 턴보다 먼저 있다면 먼저처리
+ if($gameStor->month == 1) {
+ processGoldIncome();
+ processSpring();
+ updateYearly();
+ updateQuaterly();
+ disaster();
+ tradeRate();
+ addAge();
+ // 새해 알림
+ $logger->pushGlobalActionLog("{$gameStor->year}>년이 되었습니다.");
+ $logger->flush(); //TODO: globalAction류는 전역에서 관리하는것이 좋을 듯.
+ } elseif($gameStor->month == 4) {
+ updateQuaterly();
+ disaster();
+ } elseif($gameStor->month == 7) {
+ processRiceIncome();
+ processFall();
+ updateQuaterly();
+ disaster();
+ tradeRate();
+ } elseif($gameStor->month == 10) {
+ updateQuaterly();
+ disaster();
+ }
+
+ // 이벤트 핸들러 동작
+ foreach (DB::db()->query('SELECT * from event') as $rawEvent) {
+ $eventID = $rawEvent['id'];
+ $cond = Json::decode($rawEvent['condition']);
+ $action = Json::decode($rawEvent['action']);
+ $event = new Event\EventHandler($cond, $action);
+
+ $event->tryRunEvent(['currentEventID'=>$eventID] + $gameStor->getAll(true));
+ }
+
+ postUpdateMonthly();
+
+ // 다음달로 넘김
+ $prevTurn = $nextTurn;
+ $nextTurn = addTurn($prevTurn, $gameStor->turnterm);
+ $gameStor->turntime = $prevTurn;
+ }
+
+ // 그 시각 년도,월 저장
+ turnDate($prevTurn);
+ // 현재시간의 월턴시간 이후 분단위 장수 처리
+
+ [$executionOver, $currentTurn] = static::executeGeneralCommandUntil(
+ $date, $limitActionTime, $gameStor->year, $gameStor->month
+ );
+
+ if($currentTurn !== null){
+ $gameStor->turntime = $currentTurn;
+ }
+
+ //토너먼트 처리
+ processTournament();
+ //거래 처리
+ processAuction();
+ // 잡금 해제
+ $gameStor->resetCache(true);
+ unlock();
+ }
}
\ No newline at end of file