feat: -60 turnterm 가변턴
This commit is contained in:
+24
-4
@@ -1130,6 +1130,7 @@ function CheckOverhead()
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$turnterm, $refreshLimit] = $gameStor->getValuesAsArray(['turnterm', 'refreshLimit']);
|
||||
$turnterm = abs($turnterm);
|
||||
|
||||
$nextRefreshLimit = Util::round(pow($turnterm, 0.6) * 3) * GameConst::$refreshLimitCoef;
|
||||
|
||||
@@ -1177,7 +1178,7 @@ function timeover(): bool
|
||||
list($turnterm, $turntime) = $gameStor->getValuesAsArray(['turnterm', 'turntime']);
|
||||
$diff = (new \DateTime())->getTimestamp() - (new \DateTime($turntime))->getTimestamp();
|
||||
|
||||
$t = min($turnterm, 5);
|
||||
$t = min(abs($turnterm), 5);
|
||||
|
||||
$term = $diff;
|
||||
if ($term >= $t || $term < 0) {
|
||||
@@ -1199,6 +1200,12 @@ function checkDelay()
|
||||
|
||||
// 1턴이상 갱신 없었으면 서버 지연
|
||||
$term = $gameStor->turnterm;
|
||||
|
||||
if($term < 0){
|
||||
//가변 턴에는 수행 안함!
|
||||
return;
|
||||
}
|
||||
|
||||
if ($term >= 20) {
|
||||
$threshold = 1;
|
||||
} else if ($term >= 10) {
|
||||
@@ -1278,10 +1285,14 @@ function turnDate($curtime)
|
||||
$admin = $gameStor->getValues(['startyear', 'starttime', 'turnterm', 'year', 'month']);
|
||||
|
||||
$turn = $admin['starttime'];
|
||||
$curturn = cutTurn($curtime, $admin['turnterm']);
|
||||
$term = $admin['turnterm'];
|
||||
|
||||
$num = intdiv((strtotime($curturn) - strtotime($turn)), $term * 60);
|
||||
if($term == -60){
|
||||
$num = VarTurn60::calcTurnDiff(new \DateTimeImmutable($turn), new \DateTimeImmutable($curtime));
|
||||
}
|
||||
else{
|
||||
$curturn = cutTurn($curtime, $admin['turnterm']);
|
||||
$num = intdiv((strtotime($curturn) - strtotime($turn)), $term * 60);
|
||||
}
|
||||
|
||||
$date = $admin['startyear'] * 12;
|
||||
$date += $num;
|
||||
@@ -2232,6 +2243,10 @@ function getRandTurn(RandUtil $rng, $term, ?\DateTimeInterface $baseDateTime = n
|
||||
throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
if($term == -60){
|
||||
[, $term] = VarTurn60::fromDatetime($baseDateTime)->cutTurn();
|
||||
}
|
||||
|
||||
$randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
|
||||
$randFraction = $rng->nextRangeInt(0, 999999) / 1000000; //6자리 소수
|
||||
|
||||
@@ -2247,6 +2262,11 @@ function getRandTurn2(RandUtil $rng, $term, ?\DateTimeInterface $baseDateTime =
|
||||
} else {
|
||||
throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
if($term == -60){
|
||||
[, $term] = VarTurn60::fromDatetime($baseDateTime)->cutTurn();
|
||||
}
|
||||
|
||||
$randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
|
||||
$randFraction = $rng->nextRangeInt(0, 999999) / 1000000; //6자리 소수
|
||||
|
||||
|
||||
+6
-1
@@ -181,7 +181,12 @@ function info($type = 0)
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month', 'turnterm', 'maxgeneral']);
|
||||
|
||||
$termtype = "{$admin['turnterm']}분 턴";
|
||||
$turnTermText = $admin['turnterm'].'분';
|
||||
if($admin['turnterm'] < 0){
|
||||
$turnTermText = "가변 {$admin['turnterm']}분";
|
||||
}
|
||||
|
||||
$termtype = "{$turnTermText}분 턴";
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(no) FROM general WHERE npc < 2');
|
||||
$npccount = $db->queryFirstField('SELECT count(no) FROM general WHERE npc >= 2');
|
||||
|
||||
@@ -10,6 +10,7 @@ use sammo\Enums\InheritanceKey;
|
||||
* @return int 토너먼트 초 단위
|
||||
*/
|
||||
function calcTournamentTerm(int $turnTerm): int{
|
||||
$turnTerm = abs($turnTerm);
|
||||
return Util::valueFit($turnTerm, 5, 120);
|
||||
}
|
||||
|
||||
@@ -138,6 +139,7 @@ function processTournament()
|
||||
|
||||
function getTournamentTermText(int $turnTerm)
|
||||
{
|
||||
$turnTerm = abs($turnTerm);
|
||||
$term = calcTournamentTerm($turnTerm);
|
||||
|
||||
if ($term % 60 === 0) {
|
||||
@@ -342,7 +344,7 @@ function startBetting($type)
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$year, $month, $startyear, $turnterm] = $gameStor->getValuesAsArray(['year', 'month', 'startyear', 'turnterm']);
|
||||
[$year, $month, $startyear] = $gameStor->getValuesAsArray(['year', 'month', 'startyear']);
|
||||
pushGlobalHistoryLog([
|
||||
"<S>◆</>{$year}년 {$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!"
|
||||
], $year, $month);
|
||||
|
||||
@@ -54,6 +54,7 @@ if ($session->userGrade < 5 && !$allowReset) {
|
||||
<label for="turnterm" class="col-sm-3 col-form-label">턴 시간(분)</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="turnterm" class="btn-group btn-group-toggle" data-bs-toggle="buttons">
|
||||
<input type="radio" class="btn-check" name="turnterm" id="turnterm_var60" value="-60" checked><label for="turnterm_var60" class="btn btn-secondary">가변60</label>
|
||||
<input type="radio" class="btn-check" name="turnterm" id="turnterm_120" value="120"><label for="turnterm_120" class="btn btn-secondary">120</label>
|
||||
<input type="radio" class="btn-check" name="turnterm" id="turnterm_60" value="60" checked><label for="turnterm_60" class="btn btn-secondary">60</label>
|
||||
<input type="radio" class="btn-check" name="turnterm" id="turnterm_30" value="30"><label for="turnterm_30" class="btn btn-secondary">30</label>
|
||||
|
||||
@@ -36,6 +36,7 @@ list(
|
||||
$turnterm,
|
||||
$npcmode
|
||||
) = $gameStor->getValuesAsArray(['maxgeneral', 'turnterm', 'npcmode']);
|
||||
$turnterm = abs($turnterm);
|
||||
|
||||
if($npcmode!=1){
|
||||
Json::die([
|
||||
|
||||
@@ -121,7 +121,7 @@ $builder->setOwner($userID);
|
||||
$builder->setOwnerName($userNick);
|
||||
$builder->setKillturn(5);
|
||||
$builder->setNPCType(0);
|
||||
$builder->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $env['turnterm']));
|
||||
$builder->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * abs($env['turnterm'])));
|
||||
$builder->fillRemainSpecAsZero($env);
|
||||
$builder->build($env);
|
||||
$generalID = $builder->getGeneralID();
|
||||
|
||||
@@ -60,7 +60,7 @@ $me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn);
|
||||
$me->setVar('tnmt', $tnmt);
|
||||
|
||||
if ($me->getNPCType() == 1 && $detachNPC) {
|
||||
$turnterm = $gameStor->turnterm;
|
||||
$turnterm = abs($gameStor->turnterm);
|
||||
|
||||
if ($turnterm < 10) {
|
||||
$targetKillTurn = 30 / $turnterm;
|
||||
|
||||
@@ -39,6 +39,7 @@ list(
|
||||
$npcmode,
|
||||
$turnterm
|
||||
) = $gameStor->getValuesAsArray(['year', 'month', 'maxgeneral', 'npcmode', 'turnterm']);
|
||||
$turnterm = abs($turnterm);
|
||||
|
||||
if($npcmode!=2){
|
||||
Json::die([
|
||||
|
||||
@@ -28,6 +28,7 @@ use sammo\UniqueConst;
|
||||
use sammo\UserLogger;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
use sammo\VarTurn60;
|
||||
use sammo\WebUtil;
|
||||
|
||||
use function sammo\addTurn;
|
||||
@@ -355,20 +356,28 @@ class Join extends \sammo\BaseAPI
|
||||
}
|
||||
|
||||
if ($inheritTurntimeZone !== null) {
|
||||
$inheritTurntime = $inheritTurntimeZone * $admin['turnterm'];
|
||||
$inheritTurntime += $rng->nextRangeInt(0, Util::clamp($admin['turnterm'] - 1, 0));
|
||||
$turnterm = abs($admin['turnterm']);
|
||||
$inheritTurntime = $inheritTurntimeZone * $turnterm;
|
||||
$inheritTurntime += $rng->nextRangeInt(0, Util::clamp($turnterm - 1, 0));
|
||||
|
||||
$userLogger->push(sprintf("턴 시간 %02d:%02d 로 지정", intdiv($inheritTurntime, 60), $inheritTurntime % 60), "inheritPoint");
|
||||
|
||||
$inheritTurntime += $rng->nextRangeInt(0, 999999) / 1000000;
|
||||
|
||||
$turntime = new \DateTimeImmutable(cutTurn($admin['turntime'], $admin['turnterm']));
|
||||
$turntime = new \DateTimeImmutable(cutTurn($admin['turntime'], $turnterm));
|
||||
$turntime = $turntime->add(TimeUtil::secondsToDateInterval($inheritTurntime));
|
||||
$turntime = TimeUtil::format($turntime, true);
|
||||
} else {
|
||||
$turntime = getRandTurn($rng, $admin['turnterm'], new \DateTimeImmutable($admin['turntime']));
|
||||
$turntime = getRandTurn($rng, abs($admin['turnterm']), new \DateTimeImmutable($admin['turntime']));
|
||||
}
|
||||
|
||||
if ($admin['turnterm'] == -60){
|
||||
$baseObj = VarTurn60::fromDatetime(new \DateTimeImmutable($admin['turntime']));
|
||||
$userTurnObj = VarTurn60::fromDatetime(new \DateTimeImmutable($turntime));
|
||||
if($baseObj->turnIdx != $userTurnObj->turnIdx){
|
||||
$turntime = $userTurnObj->addTurn(-1)->toDateStr();
|
||||
}
|
||||
}
|
||||
|
||||
$now = TimeUtil::now(true);
|
||||
if ($now >= $turntime) {
|
||||
|
||||
@@ -62,7 +62,7 @@ class ResetTurnTime extends \sammo\BaseAPI
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
|
||||
$currTurnTime = new DateTimeImmutable($general->getTurnTime());
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ abstract class AbsFromUserPool extends AbsGeneralPool{
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$result = [];
|
||||
$validUntil = TimeUtil::nowAddMinutes(2 * $gameStor->turnterm);
|
||||
$validUntil = TimeUtil::nowAddMinutes(2 * abs($gameStor->turnterm));
|
||||
while(count($result) < $pickCnt){
|
||||
$cand = $rng->choiceUsingWeightPair($pool);
|
||||
$poolID = $cand['id'];
|
||||
|
||||
@@ -164,7 +164,7 @@ abstract class Auction
|
||||
if ($date === null) {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
$date = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_PER_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_PER_BID) * 60
|
||||
));
|
||||
@@ -324,7 +324,7 @@ abstract class Auction
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
|
||||
if ($this->info->detail->availableLatestBidCloseDate !== null) {
|
||||
$extendedCloseDate = $now->add(TimeUtil::secondsToDateInterval(
|
||||
@@ -437,7 +437,7 @@ abstract class Auction
|
||||
$general->increaseVar($resType->value, -$morePoint);
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
$extendedCloseDate = $now->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_PER_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_PER_BID) * 60
|
||||
));
|
||||
@@ -471,7 +471,7 @@ abstract class Auction
|
||||
if ($highestBid->aux->tryExtendCloseDate) {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
|
||||
//연장 요청이 있었다.
|
||||
$extendedCloseDate = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
|
||||
@@ -58,7 +58,7 @@ abstract class AuctionBasicResource extends Auction
|
||||
|
||||
$now = new \DateTimeImmutable();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
$closeDate = $now->add(TimeUtil::secondsToDateInterval($closeTurnCnt * $turnTerm * 60));
|
||||
|
||||
$openResult = static::openAuction(new AuctionInfo(
|
||||
@@ -246,7 +246,13 @@ abstract class AuctionBasicResource extends Auction
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$date = (new DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($turnTerm * 60));
|
||||
if($turnTerm == -60){
|
||||
$date = VarTurn60::fromDatetime(new \DateTimeImmutable())->addTurn(1)->toDateStr();
|
||||
}
|
||||
else{
|
||||
$date = (new DateTimeImmutable())->add(TimeUtil::secondsToDateInterval($turnTerm * 60));
|
||||
}
|
||||
|
||||
$this->shrinkCloseDate($date);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ class AuctionUniqueItem extends Auction
|
||||
$now = new DateTimeImmutable();
|
||||
|
||||
[$turnTerm, $year, $month] = $gameStor->getValuesAsArray(['turnterm', 'year', 'month']);
|
||||
$turnTerm = abs($turnTerm);
|
||||
|
||||
$closeDate = $now->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_AUCTION_CLOSE_MINUTES, $turnTerm * static::COEFF_AUCTION_CLOSE_MINUTES) * 60
|
||||
@@ -266,7 +267,7 @@ class AuctionUniqueItem extends Auction
|
||||
}
|
||||
|
||||
if ($availableEquipUniqueCnt <= 0) {
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
//제한에 걸렸다면 자동 연장
|
||||
$extendedCloseDate = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_BY_EXTENSION_QUERY, $turnTerm * static::COEFF_EXTENSION_MINUTES_LIMIT_UNIQUE_CNT) * 60
|
||||
@@ -314,7 +315,7 @@ class AuctionUniqueItem extends Auction
|
||||
|
||||
if (!$availableItemTypes) {
|
||||
if ($isExtendCloseDateRequired) {
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$turnTerm = abs($gameStor->getValue('turnterm'));
|
||||
//동일 부위 제한에 걸렸다면 자동 연장
|
||||
$extendedCloseDate = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_LIMIT_BY_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_LIMIT_BY_BID) * 60
|
||||
|
||||
@@ -200,7 +200,7 @@ class che_불가침제의 extends Command\NationCommand
|
||||
|
||||
$now = new \DateTime($date);
|
||||
$validUntil = new \DateTime($date);
|
||||
$validMinutes = max(30, $env['turnterm'] * 3);
|
||||
$validMinutes = max(30, abs($env['turnterm']) * 3);
|
||||
$validUntil->add(new \DateInterval("PT{$validMinutes}M"));
|
||||
|
||||
$josaWa = JosaUtil::pick($nationName, '와');
|
||||
|
||||
@@ -149,7 +149,7 @@ class che_불가침파기제의 extends Command\NationCommand{
|
||||
|
||||
$now = new \DateTime($date);
|
||||
$validUntil = new \DateTime($date);
|
||||
$validMinutes = max(30, $env['turnterm']*3);
|
||||
$validMinutes = max(30, abs($env['turnterm'])*3);
|
||||
$validUntil->add(new \DateInterval("PT{$validMinutes}M"));
|
||||
|
||||
$msg = new DiplomaticMessage(
|
||||
|
||||
@@ -147,7 +147,7 @@ class che_종전제의 extends Command\NationCommand{
|
||||
|
||||
$now = new \DateTime($date);
|
||||
$validUntil = new \DateTime($date);
|
||||
$validMinutes = max(30, $env['turnterm']*3);
|
||||
$validMinutes = max(30, abs($env['turnterm'])*3);
|
||||
$validUntil->add(new \DateInterval("PT{$validMinutes}M"));
|
||||
|
||||
$msg = new DiplomaticMessage(
|
||||
|
||||
@@ -120,7 +120,7 @@ class RaiseInvader extends \sammo\Event\Action
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->setValue('isunited', 1);
|
||||
|
||||
$turnterm = $gameStor->turnterm;
|
||||
$turnterm = abs($gameStor->turnterm);
|
||||
$generalCnt = $db->queryFirstField('SELECT count(*) FROM general');
|
||||
|
||||
if ($npcEachCount < 0) {
|
||||
|
||||
@@ -134,7 +134,7 @@ class UpdateNationLevel extends \sammo\Event\Action
|
||||
if ($levelDiff) {
|
||||
//유니크 아이템 하나 돌리자
|
||||
$targetKillTurn = $env['killturn'];
|
||||
$targetKillTurn -= 24 * 60 / $env['turnterm'];
|
||||
$targetKillTurn -= 24 * 60 / abs($env['turnterm']);
|
||||
$nationGenIDList = $db->queryFirstColumn(
|
||||
'SELECT no FROM general WHERE nation = %i AND killturn >= %i AND npc < 2',
|
||||
$nation['nation'],
|
||||
|
||||
@@ -283,6 +283,7 @@ class General extends GeneralBase implements iAction
|
||||
}
|
||||
$recwar = new \DateTimeImmutable($this->getVar('recent_war'));
|
||||
$turnNow = new \DateTimeImmutable($this->getVar('turntime'));
|
||||
|
||||
$secDiff = TimeUtil::DateIntervalToSeconds($recwar->diff($turnNow));
|
||||
|
||||
if ($secDiff <= 0) {
|
||||
@@ -290,6 +291,12 @@ class General extends GeneralBase implements iAction
|
||||
return 0;
|
||||
}
|
||||
|
||||
if($turnTerm == -60){
|
||||
$turnDiff = VarTurn60::calcTurnDiff($recwar, $turnNow);
|
||||
$this->calcCache[$cacheKey] = $turnDiff;
|
||||
return $turnDiff;
|
||||
}
|
||||
|
||||
$result = intdiv(Util::toInt($secDiff), 60 * $turnTerm);
|
||||
$this->calcCache[$cacheKey] = $result;
|
||||
return $result;
|
||||
|
||||
@@ -1980,7 +1980,7 @@ class GeneralAI
|
||||
$db = DB::db();
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $general->getNationID(), 'nation_env');
|
||||
$turnTerm = $this->env['turnterm'];
|
||||
$turnTerm = abs($this->env['turnterm']);
|
||||
|
||||
//천도를 한턴 넣었다면 계속 넣는다.
|
||||
if ($lastTurn->getCommand() === '천도' && $lastTurn->getArg()['destCityID'] != $this->nation['capital']) {
|
||||
@@ -3715,7 +3715,7 @@ class GeneralAI
|
||||
$this->updateInstance();
|
||||
|
||||
//특별 메세지 있는 경우 출력
|
||||
$term = $this->env['turnterm'];
|
||||
$term = abs($this->env['turnterm']);
|
||||
if ($general->getVar('npcmsg') && $this->rng->nextBool(GameConst::$npcMessageFreqByDay * $term / (60 * 24))) {
|
||||
$src = new MessageTarget(
|
||||
$general->getID(),
|
||||
@@ -3985,7 +3985,7 @@ class GeneralAI
|
||||
|
||||
$userChiefCnt = 0;
|
||||
|
||||
$minUserKillturn = $this->env['killturn'] - Util::toInt(240 / $this->env['turnterm']);
|
||||
$minUserKillturn = $this->env['killturn'] - Util::toInt(240 / abs($this->env['turnterm']));
|
||||
$minNPCKillturn = 36;
|
||||
|
||||
foreach (Util::range($minChiefLevel, 12) as $chiefLevel) {
|
||||
|
||||
@@ -245,7 +245,16 @@ class ResetHelper{
|
||||
true
|
||||
);
|
||||
|
||||
if($sync == 0) {
|
||||
if($turnterm == -60){
|
||||
[$starttime, $yearPulled, $month] = VarTurn60::fromDatetime(new \DateTimeImmutable($turntime))->cutDay();
|
||||
if($yearPulled){
|
||||
$year = $startyear-1;
|
||||
}
|
||||
else{
|
||||
$year = $startyear;
|
||||
}
|
||||
}
|
||||
else if($sync == 0) {
|
||||
// 현재 시간을 1월로 맞춤
|
||||
$starttime = cutTurn($turntime, $turnterm);
|
||||
$month = 1;
|
||||
@@ -261,7 +270,7 @@ class ResetHelper{
|
||||
}
|
||||
}
|
||||
|
||||
$killturn = 4800 / $turnterm;
|
||||
$killturn = 4800 / abs($turnterm);
|
||||
if($npcmode == 1) { $killturn = intdiv($killturn, 3); }
|
||||
|
||||
$develcost = ($year - $startyear + 10) * 2;
|
||||
|
||||
@@ -219,11 +219,20 @@ class TurnExecutionHelper
|
||||
|
||||
$nextTurnTimeBase = $general->getAuxVar('nextTurnTimeBase');
|
||||
if($nextTurnTimeBase !== null){
|
||||
$turntime = cutTurn($turntime, $gameStor->turnterm);
|
||||
$turntimeObj = new \DateTimeImmutable($turntime);
|
||||
$turntimeObj = $turntimeObj->add(TimeUtil::secondsToDateInterval($nextTurnTimeBase));
|
||||
$turntime = TimeUtil::format($turntimeObj, true);
|
||||
$general->setAuxVar('nextTurnTimeBase', null);
|
||||
if($gameStor->turnterm == -60){
|
||||
[$turntime, $nextTurnterm] = VarTurn60::fromDatetime(new \DateTimeImmutable($turntime))->cutTurn();
|
||||
$turntimeObj = new \DateTimeImmutable($turntime);
|
||||
$turntimeObj = $turntimeObj->add(TimeUtil::secondsToDateInterval($nextTurnTimeBase * $nextTurnterm / 60));
|
||||
$turntime = TimeUtil::format($turntimeObj, true);
|
||||
$general->setAuxVar('nextTurnTimeBase', null);
|
||||
}
|
||||
else {
|
||||
$turntime = cutTurn($turntime, $gameStor->turnterm);
|
||||
$turntimeObj = new \DateTimeImmutable($turntime);
|
||||
$turntimeObj = $turntimeObj->add(TimeUtil::secondsToDateInterval($nextTurnTimeBase));
|
||||
$turntime = TimeUtil::format($turntimeObj, true);
|
||||
$general->setAuxVar('nextTurnTimeBase', null);
|
||||
}
|
||||
}
|
||||
|
||||
$general->setVar('turntime', $turntime);
|
||||
|
||||
@@ -68,7 +68,7 @@ import { formatTime } from "@/util/formatTime";
|
||||
import { mb_strwidth } from "@/util/mb_strwidth";
|
||||
import { parseTime } from "@/util/parseTime";
|
||||
import type { StoredActionsHelper } from "@/util/StoredActionsHelper";
|
||||
import addMinutes from "date-fns/esm/addMinutes/index";
|
||||
import { addMinutes } from "date-fns/addMinutes";
|
||||
import { range } from "lodash-es";
|
||||
import { inject, onMounted, ref, type PropType } from "vue";
|
||||
import VueTypes from "vue-types";
|
||||
@@ -76,6 +76,7 @@ import DragSelect from "@/components/DragSelect.vue";
|
||||
import { BButton } from "bootstrap-vue-next";
|
||||
import { QueryActionHelper } from "@/util/QueryActionHelper";
|
||||
import type { ChiefResponse } from "@/defs/API/NationCommand";
|
||||
import { VarTurn60 } from "@/varTurn60";
|
||||
|
||||
const props = defineProps({
|
||||
style: VueTypes.object.isRequired,
|
||||
@@ -198,10 +199,21 @@ if (!props.officer || !props.officer.turnTime) {
|
||||
}
|
||||
} else {
|
||||
const baseTurnTime = parseTime(props.officer.turnTime);
|
||||
for (const idx of range(props.officer.turn.length)) {
|
||||
turnTimes.value.push(
|
||||
formatTime(addMinutes(baseTurnTime, idx * props.turnTerm), props.turnTerm >= 5 ? "HH:mm" : "mm:ss")
|
||||
);
|
||||
if(props.turnTerm == -60){
|
||||
const baseTurnTimeObj = VarTurn60.fromDatetime(baseTurnTime);
|
||||
for (const idx of range(props.officer.turn.length)) {
|
||||
turnTimes.value.push(
|
||||
formatTime(baseTurnTimeObj.addTurn(idx).toDate(), "HH:mm")
|
||||
);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (const idx of range(props.officer.turn.length)) {
|
||||
turnTimes.value.push(
|
||||
formatTime(addMinutes(baseTurnTime, idx * props.turnTerm), props.turnTerm >= 5 ? "HH:mm" : "mm:ss")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -310,14 +310,13 @@ declare const staticValues: {
|
||||
import { reactive, ref, watch } from "vue";
|
||||
import "@scss/game_bg.scss";
|
||||
import TopBackBar from "@/components/TopBackBar.vue";
|
||||
import _ from "lodash-es";
|
||||
import { sum } from "lodash-es";
|
||||
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
||||
import { SammoAPI } from "./SammoAPI";
|
||||
import { InheritResetStat, type inheritBuffType, type InheritPointLogItem } from "./defs/API/InheritAction";
|
||||
import * as JosaUtil from "@/util/JosaUtil";
|
||||
import { BButton } from "bootstrap-vue-next";
|
||||
import { unwrap } from "./util/unwrap";
|
||||
import { add as dateAdd } from 'date-fns';
|
||||
|
||||
const inheritanceViewText: Record<InheritanceViewType, { title: string; info: string }> = {
|
||||
sum: {
|
||||
@@ -428,7 +427,7 @@ const title = "유산 관리";
|
||||
|
||||
const items = ref(
|
||||
(() => {
|
||||
const totalPoint = Math.floor(_.sum(Object.values(staticValues.items)));
|
||||
const totalPoint = Math.floor(sum(Object.values(staticValues.items)));
|
||||
const previousPoint = Math.floor(staticValues.items["previous"]);
|
||||
const newPoint = Math.floor(totalPoint - previousPoint);
|
||||
const result: Record<InheritanceViewType, number> = {
|
||||
|
||||
+1
-1
@@ -485,7 +485,7 @@ watch(inheritCity, (newValue: undefined | number) => {
|
||||
const inheritTurnTimeZone = ref<number>();
|
||||
const turnTimeZoneList: string[] = (()=>{
|
||||
const result: string[] = [];
|
||||
const zoneSec = turnterm; // * 60 / 60
|
||||
const zoneSec = Math.abs(turnterm); // * 60 / 60
|
||||
let zoneCur = 0;
|
||||
for(const idx of range(60)){
|
||||
const zoneNext = zoneCur + zoneSec;
|
||||
|
||||
@@ -276,7 +276,7 @@ declare const staticValues: {
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import addMinutes from "date-fns/esm/addMinutes";
|
||||
import { addMinutes } from "date-fns/addMinutes";
|
||||
import { isString, range, trim } from "lodash-es";
|
||||
import queryString from "query-string";
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
@@ -297,6 +297,7 @@ import { QueryActionHelper } from "./util/QueryActionHelper";
|
||||
import SimpleClock from "./components/SimpleClock.vue";
|
||||
import type { ReservedCommandResponse } from "./defs/API/Command";
|
||||
import { unwrap } from "./util/unwrap";
|
||||
import { VarTurn60 } from "./varTurn60";
|
||||
|
||||
defineExpose({
|
||||
updateCommandTable,
|
||||
@@ -544,7 +545,13 @@ async function reloadCommandList() {
|
||||
});
|
||||
|
||||
yearMonth += 1;
|
||||
nextTurnTime = addMinutes(nextTurnTime, result.turnTerm);
|
||||
if(result.turnTerm == -60){
|
||||
nextTurnTime = VarTurn60.fromDatetime(nextTurnTime).addTurn(1).toDate();
|
||||
}
|
||||
else{
|
||||
nextTurnTime = addMinutes(nextTurnTime, result.turnTerm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
serverNow.value = parseTime(result.date);
|
||||
|
||||
@@ -256,7 +256,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import addMinutes from "date-fns/esm/addMinutes";
|
||||
import { addMinutes } from "date-fns/addMinutes";
|
||||
import queryString from "query-string";
|
||||
import { onMounted, ref, watch, type PropType, inject, type Ref } from "vue";
|
||||
import { formatTime } from "@util/formatTime";
|
||||
@@ -282,6 +282,7 @@ import { unwrap_err } from "@/util/unwrap_err";
|
||||
import type { GameConstStore } from "@/GameConstStore";
|
||||
import { postFilterNationCommandGen } from "@/utilGame/postFilterNationCommandGen";
|
||||
import { unwrap } from "@/util/unwrap";
|
||||
import { VarTurn60 } from "@/varTurn60";
|
||||
|
||||
const toasts = unwrap(useToast());
|
||||
|
||||
@@ -536,13 +537,19 @@ function updateCommandList() {
|
||||
...obj,
|
||||
year,
|
||||
month,
|
||||
time: formatTime(nextTurnTime, props.turnTerm >= 5 ? "HH:mm" : "mm:ss"),
|
||||
time: formatTime(nextTurnTime, Math.abs(props.turnTerm) >= 5 ? "HH:mm" : "mm:ss"),
|
||||
tooltip: tooltip.length == 0 ? undefined : tooltip.join("\n"),
|
||||
style,
|
||||
});
|
||||
|
||||
yearMonth += 1;
|
||||
nextTurnTime = addMinutes(nextTurnTime, props.turnTerm);
|
||||
|
||||
if(props.turnTerm == -60){
|
||||
nextTurnTime = VarTurn60.fromDatetime(nextTurnTime).addTurn(1).toDate();
|
||||
}
|
||||
else{
|
||||
nextTurnTime = addMinutes(nextTurnTime, props.turnTerm);
|
||||
}
|
||||
}
|
||||
reservedCommandList.value = _reservedCommandList;
|
||||
updated.value = true;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<AutorunInfo :autorunMode="globalInfo.autorunUser" />
|
||||
</div>
|
||||
<div class="s-border-t col py-2 col-8 col-lg-4 subYearMonth">
|
||||
현재: {{ globalInfo.year }}年 {{ globalInfo.month }}月 ({{ globalInfo.turnterm }}분 턴 서버)
|
||||
현재: {{ globalInfo.year }}年 {{ globalInfo.month }}月 ({{ globalInfo.turnterm == -60 ? '가변 60' : globalInfo.turnterm }}분 턴 서버)
|
||||
</div>
|
||||
<div class="s-border-t col py-2 col-4 col-lg-2 subOnlineUserCnt">
|
||||
전체 접속자 수: {{ (globalInfo.onlineUserCnt ?? 0).toLocaleString() }}명
|
||||
|
||||
@@ -175,8 +175,9 @@ import { clamp } from "lodash-es";
|
||||
import { formatCityName } from "@/utilGame/formatCityName";
|
||||
import { isValidObjKey } from "@/utilGame/isValidObjKey";
|
||||
import { calcInjury } from "@/utilGame/calcInjury";
|
||||
import { addMinutes } from "date-fns/esm";
|
||||
import { addMinutes } from "date-fns/addMinutes";
|
||||
import type { GameIActionInfo } from "@/defs/GameObj";
|
||||
import { VarTurn60 } from "@/varTurn60";
|
||||
const imagePath = window.pathConfig.gameImage;
|
||||
const gameConstStore = unwrap(inject<Ref<GameConstStore>>("gameConstStore"));
|
||||
const props = defineProps<{
|
||||
@@ -278,7 +279,12 @@ watch(
|
||||
() => {
|
||||
let turnTime = parseTime(general.value.turntime);
|
||||
if (turnTime.getTime() < props.lastExecuted.getTime()) {
|
||||
turnTime = addMinutes(turnTime, props.turnTerm);
|
||||
if(props.turnTerm == -60){
|
||||
turnTime = VarTurn60.fromDatetime(turnTime).addTurn(1).toDate();
|
||||
}
|
||||
else {
|
||||
turnTime = addMinutes(turnTime, props.turnTerm);
|
||||
}
|
||||
}
|
||||
nextExecuteMinute.value = Math.floor(clamp((turnTime.getTime() - props.lastExecuted.getTime()) / 60000, 0, 999));
|
||||
},
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { MsgItem, MsgTarget, MsgType } from "@/defs/API/Message";
|
||||
import { parseTime } from "@/util/parseTime";
|
||||
import { differenceInMilliseconds, addMinutes } from "date-fns/esm";
|
||||
import { addMinutes, differenceInMilliseconds } from "date-fns";
|
||||
import { computed, onMounted, ref, toRef, watch, type ComputedRef, type Ref } from "vue";
|
||||
import linkifyStr from "linkify-string";
|
||||
import { SammoAPI } from "@/SammoAPI";
|
||||
|
||||
@@ -93,7 +93,7 @@ $(function () {
|
||||
const runAnalysis = async function () {
|
||||
let realKillturn = killturn;
|
||||
if(autorun_user && autorun_user.limit_minutes){
|
||||
realKillturn -= autorun_user.limit_minutes / turnterm;
|
||||
realKillturn -= autorun_user.limit_minutes / Math.abs(turnterm);
|
||||
}
|
||||
const $content = $('#on_mover .content');
|
||||
try {
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ const descriptor: NamedRules<InstallFormType> = {
|
||||
turnterm: {
|
||||
required: true,
|
||||
type: "enum",
|
||||
enum: [1, 2, 5, 10, 20, 30, 60, 120],
|
||||
enum: [1, 2, 5, 10, 20, 30, 60, 120, -60],
|
||||
transform: parseInt,
|
||||
},
|
||||
sync: {
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ import axios from 'axios';
|
||||
import { convertFormData } from '@util/convertFormData';
|
||||
import { isBrightColor } from "@util/isBrightColor";
|
||||
import { unwrap } from '@util/unwrap';
|
||||
import _, { isError, isString } from 'lodash-es';
|
||||
import { isError, isString, last, trim } from 'lodash-es';
|
||||
import { addMinutes } from 'date-fns';
|
||||
import { parseTime } from '@util/parseTime';
|
||||
import { formatTime } from '@util/formatTime';
|
||||
@@ -234,7 +234,7 @@ function redrawMsg(msgResponse: MsgResponse, addFront: boolean): MsgResponse {
|
||||
if (!msgList || msgList.length == 0) {
|
||||
continue;
|
||||
}
|
||||
const lastMsg = unwrap(_.last(msgList));
|
||||
const lastMsg = unwrap(last(msgList));
|
||||
minMsgSeq[msgType] = Math.min(minMsgSeq[msgType], lastMsg.id);
|
||||
}
|
||||
return obj;
|
||||
@@ -605,7 +605,7 @@ function activateMessageForm() {
|
||||
|
||||
$msgSubmit.on('click', async function () {
|
||||
|
||||
const text = _.trim(unwrap_any<string>($msgInput.val()));
|
||||
const text = trim(unwrap_any<string>($msgInput.val()));
|
||||
$msgInput.val('').trigger('focus');
|
||||
|
||||
const targetMailbox = unwrap_any<string>($mailboxList.val());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { clamp } from 'lodash-es';
|
||||
export function calcTournamentTerm(turnTerm: number): number{
|
||||
turnTerm = Math.abs(turnTerm);
|
||||
return clamp(turnTerm, 5, 120);
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
import {
|
||||
addSeconds,
|
||||
addDays,
|
||||
differenceInCalendarDays,
|
||||
} from 'date-fns';
|
||||
import {
|
||||
toZonedTime,
|
||||
fromZonedTime,
|
||||
} from 'date-fns-tz';
|
||||
import { formatTime } from './util/formatTime';
|
||||
|
||||
import { parse as parseDF, isValid } from 'date-fns';
|
||||
|
||||
export const SEOUL_TZ = 'Asia/Seoul';
|
||||
|
||||
// 문자열이 타임존/오프셋을 포함하는지 단순 판별 (ISO 형태 위주)
|
||||
const TZ_OFFSET_RE = /([zZ]|[+-]\d{2}:?\d{2})$/;
|
||||
|
||||
function tryParseWithFormats(s: string): Date | null {
|
||||
const fmts = [
|
||||
"yyyy-MM-dd'T'HH:mm:ss", // 2025-10-31T09:30:00
|
||||
'yyyy-MM-dd HH:mm:ss', // 2025-10-31 09:30:00
|
||||
"yyyy-MM-dd'T'HH:mm", // 2025-10-31T09:30
|
||||
'yyyy-MM-dd HH:mm', // 2025-10-31 09:30
|
||||
'yyyy-MM-dd', // 2025-10-31
|
||||
];
|
||||
for (const fmt of fmts) {
|
||||
const d = parseDF(s, fmt, new Date(0));
|
||||
if (isValid(d)) return d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 문자열/Date/number 입력을 UTC Date로 정규화
|
||||
* - 문자열에 오프셋/타임존이 없으면 Asia/Seoul 기준 “벽시계 시간”으로 간주
|
||||
* - number는 epoch ms로 간주 (epoch s면 직접 *1000 해서 넘겨줘)
|
||||
*/
|
||||
export function toUTC(input: string | Date | number): Date {
|
||||
if (input instanceof Date) {
|
||||
return new Date(input.getTime()); // 이미 절대시간
|
||||
}
|
||||
if (typeof input === 'number') {
|
||||
return new Date(input); // epoch ms
|
||||
}
|
||||
const s = input.trim();
|
||||
|
||||
// 오프셋/타임존이 명시된 ISO라면 기본 파서로 (절대시간 유지)
|
||||
if (TZ_OFFSET_RE.test(s)) {
|
||||
const d = new Date(s);
|
||||
if (isValid(d)) return d;
|
||||
}
|
||||
|
||||
// 오프셋이 없는 문자열 → 서울 벽시계로 파싱해서 UTC로 변환
|
||||
const parsedLocal = tryParseWithFormats(s) ?? new Date(s);
|
||||
if (!isValid(parsedLocal)) {
|
||||
throw new Error(`Unparsable date string: "${input}"`);
|
||||
}
|
||||
// parsedLocal는 "그 문자열 그대로의 Y/M/D h:m:s"를 들고 있음(타임존 無)
|
||||
// 이를 Asia/Seoul 로컬로 간주해 UTC로 변환
|
||||
const utc = fromZonedTime(parsedLocal, SEOUL_TZ);
|
||||
return utc;
|
||||
}
|
||||
|
||||
export class VarTurn60 {
|
||||
static readonly TZ = 'Asia/Seoul';
|
||||
static readonly MonthAdjustOffset = 2;
|
||||
|
||||
// [turnIdx, minOffset, turnTermMinutes]
|
||||
static readonly min30ToTurn: Array<[number, number, number]> = [
|
||||
[0, 0, 120],
|
||||
[0, 30, 120],
|
||||
[0, 60, 120],
|
||||
[0, 90, 120],
|
||||
[1, 0, 120],
|
||||
[1, 30, 120],
|
||||
[1, 60, 120],
|
||||
[1, 90, 120],
|
||||
[2, 0, 120],
|
||||
[2, 30, 120],
|
||||
[2, 60, 120],
|
||||
[2, 90, 120],
|
||||
[3, 0, 60],
|
||||
[3, 30, 60],
|
||||
[4, 0, 60],
|
||||
[4, 30, 60],
|
||||
[5, 0, 60],
|
||||
[5, 30, 60],
|
||||
[6, 0, 60],
|
||||
[6, 30, 60],
|
||||
[7, 0, 60],
|
||||
[7, 30, 60],
|
||||
[8, 0, 60],
|
||||
[8, 30, 60],
|
||||
[9, 0, 60],
|
||||
[9, 30, 60],
|
||||
[10, 0, 60],
|
||||
[10, 30, 60],
|
||||
[11, 0, 60],
|
||||
[11, 30, 60],
|
||||
[12, 0, 60],
|
||||
[12, 30, 60],
|
||||
[13, 0, 60],
|
||||
[13, 30, 60],
|
||||
[14, 0, 60],
|
||||
[14, 30, 60],
|
||||
[15, 0, 60],
|
||||
[15, 30, 60],
|
||||
[16, 0, 30],
|
||||
[17, 0, 30],
|
||||
[18, 0, 30],
|
||||
[19, 0, 30],
|
||||
[20, 0, 30],
|
||||
[21, 0, 30],
|
||||
[22, 0, 60],
|
||||
[22, 30, 60],
|
||||
[23, 0, 60],
|
||||
[23, 30, 60],
|
||||
];
|
||||
|
||||
// [hour, minOffset, turnTermMinutes] for turnIdx 0..23
|
||||
static readonly turnToHM: Array<[number, number, number]> = [
|
||||
[0, 0, 120],
|
||||
[2, 0, 120],
|
||||
[4, 0, 120],
|
||||
[6, 0, 60],
|
||||
[7, 0, 60],
|
||||
[8, 0, 60],
|
||||
[9, 0, 60],
|
||||
[10, 0, 60],
|
||||
[11, 0, 60],
|
||||
[12, 0, 60],
|
||||
[13, 0, 60],
|
||||
[14, 0, 60],
|
||||
[15, 0, 60],
|
||||
[16, 0, 60],
|
||||
[17, 0, 60],
|
||||
[18, 0, 60],
|
||||
[19, 0, 30],
|
||||
[19, 30, 30],
|
||||
[20, 0, 30],
|
||||
[20, 30, 30],
|
||||
[21, 0, 30],
|
||||
[21, 30, 30],
|
||||
[22, 0, 60],
|
||||
[23, 0, 60],
|
||||
];
|
||||
|
||||
constructor(
|
||||
public readonly baseDayUTC: Date, // UTC 기준 하루의 00:00 (Seoul 기준)
|
||||
public readonly turnIdx: number, // 0..23
|
||||
public readonly secOffset: number // seconds within the turn
|
||||
) { }
|
||||
|
||||
// ----- Utilities -----
|
||||
|
||||
/** date → 서울 자정 (UTC 기준 Date) */
|
||||
private static toSeoulMidnightUTC(dateUTC: Date): Date {
|
||||
const zoned = toZonedTime(dateUTC, this.TZ);
|
||||
const midnightInSeoul = new Date(
|
||||
zoned.getFullYear(), zoned.getMonth(), zoned.getDate(), 0, 0, 0, 0
|
||||
);
|
||||
return fromZonedTime(midnightInSeoul, this.TZ);
|
||||
}
|
||||
|
||||
private static format(dateUTC: Date, withFraction = true): string {
|
||||
const zoned = toZonedTime(dateUTC, this.TZ);
|
||||
return formatTime(zoned, withFraction);
|
||||
}
|
||||
|
||||
private static addSecondsUTC(base: Date, sec: number): Date {
|
||||
return addSeconds(base, sec);
|
||||
}
|
||||
|
||||
private static addDaysUTC(base: Date, days: number): Date {
|
||||
return addDays(base, days);
|
||||
}
|
||||
|
||||
// ----- Core Logic -----
|
||||
|
||||
|
||||
static fromDatetime(input: string | Date | number): VarTurn60 {
|
||||
const utc = toUTC(input);
|
||||
const baseDayUTC = this.toSeoulMidnightUTC(utc);
|
||||
const zoned = toZonedTime(utc, this.TZ);
|
||||
|
||||
const totalSec = zoned.getHours() * 3600 + zoned.getMinutes() * 60 + zoned.getSeconds();
|
||||
const min30 = Math.floor(totalSec / 1800);
|
||||
if (min30 < 0 || min30 >= 48) throw new RangeError('half-hour index out of range');
|
||||
const [turnIdx, minOffset] = this.min30ToTurn[min30];
|
||||
const secOffset = totalSec - 1800 * min30 + minOffset * 60;
|
||||
|
||||
return new VarTurn60(baseDayUTC, turnIdx, secOffset);
|
||||
}
|
||||
|
||||
static calcTurnDiff(a: string | Date | number, b: string | Date | number): number {
|
||||
const aObj = this.fromDatetime(a);
|
||||
const bObj = this.fromDatetime(b);
|
||||
const dayDiff = differenceInCalendarDays(bObj.baseDayUTC, aObj.baseDayUTC);
|
||||
return dayDiff * 24 + (bObj.turnIdx - aObj.turnIdx);
|
||||
}
|
||||
|
||||
cutTurn(withFraction = true): [string, number] {
|
||||
const [hour, minOffset, turnTerm] = VarTurn60.turnToHM[this.turnIdx];
|
||||
const sec = (hour * 60 + minOffset) * 60;
|
||||
const date = VarTurn60.addSecondsUTC(this.baseDayUTC, sec);
|
||||
return [VarTurn60.format(date, withFraction), turnTerm];
|
||||
}
|
||||
|
||||
toDate(): Date {
|
||||
const [hour, minOffset] = VarTurn60.turnToHM[this.turnIdx];
|
||||
const sec = (hour * 60 + minOffset) * 60 + this.secOffset;
|
||||
const date = toZonedTime(VarTurn60.addSecondsUTC(this.baseDayUTC, sec), SEOUL_TZ);
|
||||
return date;
|
||||
}
|
||||
|
||||
toDateStr(withFraction = true): string {
|
||||
const [hour, minOffset] = VarTurn60.turnToHM[this.turnIdx];
|
||||
const sec = (hour * 60 + minOffset) * 60 + this.secOffset;
|
||||
const date = VarTurn60.addSecondsUTC(this.baseDayUTC, sec);
|
||||
return VarTurn60.format(date, withFraction);
|
||||
}
|
||||
|
||||
cutDay(withFraction = true): [string, boolean, number] {
|
||||
const newMonth = ((this.turnIdx + VarTurn60.MonthAdjustOffset) % 12) + 1;
|
||||
const moved = this.addTurn(-(newMonth - 1));
|
||||
const [dateStr] = moved.cutTurn(withFraction);
|
||||
const yearPulled = newMonth > 3;
|
||||
return [dateStr, yearPulled, newMonth];
|
||||
}
|
||||
|
||||
addTurn(moreTurn: number): VarTurn60 {
|
||||
let dayDiff = Math.trunc(moreTurn / 24);
|
||||
moreTurn %= 24;
|
||||
|
||||
let nextTurnIdx = this.turnIdx + moreTurn;
|
||||
if (nextTurnIdx < 0) {
|
||||
dayDiff -= 1;
|
||||
nextTurnIdx += 24;
|
||||
} else if (nextTurnIdx >= 24) {
|
||||
dayDiff += 1;
|
||||
nextTurnIdx -= 24;
|
||||
}
|
||||
|
||||
const [, , oldTurnTerm] = VarTurn60.turnToHM[this.turnIdx];
|
||||
const [, , nextTurnTerm] = VarTurn60.turnToHM[nextTurnIdx];
|
||||
|
||||
let nextSecOffset = this.secOffset;
|
||||
if (oldTurnTerm !== nextTurnTerm) {
|
||||
nextSecOffset = (nextSecOffset * nextTurnTerm) / oldTurnTerm;
|
||||
const cap = nextTurnTerm * 60 - 1;
|
||||
if (nextSecOffset < 0) nextSecOffset = 0;
|
||||
if (nextSecOffset > cap) nextSecOffset = cap;
|
||||
}
|
||||
|
||||
const nextBaseDayUTC =
|
||||
dayDiff === 0 ? this.baseDayUTC : VarTurn60.addDaysUTC(this.baseDayUTC, dayDiff);
|
||||
|
||||
return new VarTurn60(nextBaseDayUTC, nextTurnIdx, nextSecOffset);
|
||||
}
|
||||
}
|
||||
@@ -272,7 +272,7 @@ class Session
|
||||
return $this;
|
||||
}
|
||||
|
||||
$turnterm = $gameStor->turnterm;
|
||||
$turnterm = abs($gameStor->turnterm);
|
||||
$isUnited = $gameStor->isunited != 0;
|
||||
|
||||
$generalID = $general['no'];
|
||||
|
||||
Reference in New Issue
Block a user