danoniplus 45.3.1 → 45.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/danoni_main.js CHANGED
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * Source by tickle
6
6
  * Created : 2018/10/08
7
- * Revised : 2026/03/02
7
+ * Revised : 2026/03/05
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 45.3.1`;
12
- const g_revisedDate = `2026/03/02`;
11
+ const g_version = `Ver 45.5.0`;
12
+ const g_revisedDate = `2026/03/05`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -6456,6 +6456,7 @@ const commonSettingBtn = _labelName => {
6456
6456
  const switchSave = evt => {
6457
6457
  const from = boolToSwitch(g_stateObj.dataSaveFlg);
6458
6458
  g_stateObj.dataSaveFlg = !g_stateObj.dataSaveFlg;
6459
+ updateSettingSummary();
6459
6460
 
6460
6461
  const to = boolToSwitch(g_stateObj.dataSaveFlg);
6461
6462
  evt.target.classList.replace(g_cssObj[`button_${from}`], g_cssObj[`button_${to}`]);
@@ -6517,7 +6518,7 @@ const commonSettingBtn = _labelName => {
6517
6518
 
6518
6519
  const makeSettingSummary = () => {
6519
6520
  const tmpDiv = createEmptySprite(divRoot, `settingSumSprite`, g_windowObj.settingSumSprite);
6520
- tmpDiv.style.background = g_headerObj.baseBrightFlg ? `#ffffffcc` : `#000000cc`;
6521
+ tmpDiv.style.background = g_headerObj.baseBrightFlg ? `#ffffffee` : `#000000cc`;
6521
6522
 
6522
6523
  multiAppend(tmpDiv,
6523
6524
  createDivCss2Label(`lblSummaryHeader`, g_lblNameObj.settingSummary, g_lblPosObj.lblSummaryHeader),
@@ -6553,14 +6554,18 @@ const updateSettingSummary = () => {
6553
6554
  const orgShuffleFlg = g_keyObj[`shuffle${keyCtrlPtn}`].filter((shuffleGr, j) => shuffleGr !== g_keyObj[`shuffle${keyCtrlPtn}_0d`][j]).length === 0;
6554
6555
  const shuffleName = `${getStgDetailName(g_stateObj.shuffle)}${!orgShuffleFlg && !g_stateObj.shuffle.endsWith(`+`) ? getStgDetailName('(S)') : ''}`;
6555
6556
  const settingData = getSelectedSettingList(shuffleName);
6556
-
6557
- document.getElementById(`lblSummaryDifInfo`).innerHTML = settingData.difData;
6558
- document.getElementById(`lblSummaryPlaystyleInfo`).innerHTML = settingData.playStyleData;
6559
- document.getElementById(`lblSummaryDisplayInfo`).innerHTML = settingData.displayData;
6560
- document.getElementById(`lblSummaryDisplay2Info`).innerHTML = settingData.display2Data;
6561
- document.getElementById(`lblSummaryEnvironment`).innerHTML =
6557
+ const estimatedHighscoreCondition = g_stateObj.dataSaveFlg && (g_stateObj.autoPlay !== C_FLG_ALL && g_headerObj.playbackRate === 1 && g_stateObj.fadein < 10 &&
6558
+ (g_stateObj.shuffle === C_FLG_OFF || (g_stateObj.shuffle.endsWith(`Mirror`) && orgShuffleFlg)));
6559
+
6560
+ document.getElementById(`lblSummaryDifInfo`).innerHTML = settingData.difData + `${estimatedHighscoreCondition ? '' : ` | <span class="common_kita common_bold">No Records</span>`}`;
6561
+ document.getElementById(`lblSummaryPlaystyleInfo`).textContent = settingData.playStyleData;
6562
+ document.getElementById(`lblSummaryDisplayInfo`).textContent = settingData.displayData;
6563
+ document.getElementById(`lblSummaryDisplay2Info`).textContent = settingData.display2Data;
6564
+ document.getElementById(`lblSummaryEnvironment`).textContent =
6562
6565
  `(Adj: ${g_stateObj.adjustment} f, Volume: ${g_stateObj.volume}%, ` +
6563
6566
  `ColorType: ${g_colorType}, KeyPattern: ${g_keyObj.currentPtn === -1 ? 'Self' : g_keyObj.currentPtn + 1})`;
6567
+
6568
+ g_customJsObj.settingSummary.forEach(func => func());
6564
6569
  };
6565
6570
 
6566
6571
  /**
@@ -8692,9 +8697,67 @@ const exSettingInit = () => {
8692
8697
  createEmptySprite(divRoot, `optionsprite`, g_windowObj.optionSprite);
8693
8698
  const spriteList = setSpriteList(g_settingPos.exSetting);
8694
8699
 
8695
- createGeneralSetting(spriteList.playWindow, `playWindow`);
8700
+ /**
8701
+ * 拡張ボタンの表示・非表示と通常ボタンの幅変更
8702
+ * @param {string} _name
8703
+ * @param {string} _default
8704
+ */
8705
+ const setExpandedBtnSiz = (_name, _default = C_FLG_OFF) => {
8706
+ const camelH = toCapitalize(_name);
8707
+ if (g_stateObj[_name] === _default) {
8708
+ $id(`lnk${camelH}Type`).display = C_DIS_NONE;
8709
+ $id(`lnk${camelH}`).left = wUnit(g_limitObj.setLblLeft);
8710
+ $id(`lnk${camelH}`).width = wUnit(g_limitObj.setLblWidth);
8711
+ } else {
8712
+ $id(`lnk${camelH}Type`).display = C_DIS_INHERIT;
8713
+ $id(`lnk${camelH}`).left = wUnit(g_limitObj.setLblLeftShort);
8714
+ $id(`lnk${camelH}`).width = wUnit(g_limitObj.setLblWidthShort);
8715
+ }
8716
+ };
8717
+
8718
+ /**
8719
+ * 拡張ボタンの作成
8720
+ * @param {string} _name
8721
+ * @returns {HTMLDivElement}
8722
+ */
8723
+ const createExpandedBtn = _name =>
8724
+ createCss2Button(`lnk${toCapitalize(_name)}Type`, getStgDetailName(g_stateObj[`${_name}Type`]),
8725
+ () => {
8726
+ setSetting(1, `${_name}Type`);
8727
+ createExpandedScView(_name);
8728
+ },
8729
+ Object.assign(g_lblPosObj.btnReverse, {
8730
+ cxtFunc: () => {
8731
+ setSetting(-1, `${_name}Type`);
8732
+ createExpandedScView(_name);
8733
+ },
8734
+ title: g_msgObj[`${_name}Type`] ?? ``,
8735
+ }), g_cssObj.button_Default, g_cssObj.button_RevON);
8736
+
8737
+ /**
8738
+ * 拡張ボタンのショートカット表示
8739
+ * @param {string} _name
8740
+ */
8741
+ const createExpandedScView = _name =>
8742
+ createScText(document.getElementById(`lnk${toCapitalize(_name)}Type`), `${toCapitalize(_name)}Type`, {
8743
+ displayName: `exSetting`, targetLabel: `lnk${toCapitalize(_name)}Type`, x: -13
8744
+ });
8745
+
8746
+ createGeneralSetting(spriteList.playWindow, `playWindow`, {
8747
+ addRFunc: () => setExpandedBtnSiz(`playWindow`, `Default`),
8748
+ });
8749
+ spriteList.playWindow.appendChild(createExpandedBtn(`playWindow`));
8750
+ setExpandedBtnSiz(`playWindow`, `Default`);
8751
+ createExpandedScView(`playWindow`);
8752
+
8696
8753
  createGeneralSetting(spriteList.stepArea, `stepArea`);
8697
- createGeneralSetting(spriteList.frzReturn, `frzReturn`);
8754
+ createGeneralSetting(spriteList.frzReturn, `frzReturn`, {
8755
+ addRFunc: () => setExpandedBtnSiz(`frzReturn`),
8756
+ });
8757
+ spriteList.frzReturn.appendChild(createExpandedBtn(`frzReturn`));
8758
+ setExpandedBtnSiz(`frzReturn`);
8759
+ createExpandedScView(`frzReturn`);
8760
+
8698
8761
  createGeneralSetting(spriteList.shaking, `shaking`);
8699
8762
  createGeneralSetting(spriteList.effect, `effect`, {
8700
8763
  addRFunc: () => {
@@ -11695,7 +11758,7 @@ const getArrowSettings = () => {
11695
11758
 
11696
11759
  if (g_stateObj.playWindow.endsWith(`SideScroll`)) {
11697
11760
  if (g_stateObj.rotateEnabled) {
11698
- const sign = g_stateObj.playWindow === `SideScroll` ? 1 : -1;
11761
+ const sign = g_stateObj.playWindowType === `Reverse` ? -1 : 1;
11699
11762
  changeStepRtn(`stepRtn`, 90 * sign);
11700
11763
  changeStepRtn(`stepHitRtn`, 90 * sign);
11701
11764
  changeStepRtn(`arrowRtn`, 90 * sign);
@@ -11898,6 +11961,11 @@ const getArrowSettings = () => {
11898
11961
 
11899
11962
  // FrzReturnの初期化
11900
11963
  g_workObj.frzReturnFlg = false;
11964
+ g_workObj.frzReturnSeq = g_frzReturnSeqFunc.get(g_stateObj.frzReturnType)();
11965
+ if (g_workObj.frzReturnTimerId) {
11966
+ clearTimeout(g_workObj.frzReturnTimerId);
11967
+ g_workObj.frzReturnTimerId = null;
11968
+ }
11901
11969
 
11902
11970
  // AutoRetryの初期化
11903
11971
  g_workObj.autoRetryFlg = false;
@@ -11970,9 +12038,11 @@ const getArrowSettings = () => {
11970
12038
  }
11971
12039
  }
11972
12040
 
11973
- // Shaking: Drunkでの画面揺れ設定 (X方向、Y方向)
12041
+ // Shaking: Drunkでの画面揺れ設定 (X方向、Y方向、移動軸条件、回転軸条件)
11974
12042
  g_workObj.drunkXFlg = false;
11975
12043
  g_workObj.drunkYFlg = false;
12044
+ g_workObj.drunkAxisFlg = false;
12045
+ g_workObj.drunkRotateFlg = false;
11976
12046
 
11977
12047
  // AppearanceFilterの可視範囲設定
11978
12048
  g_workObj.aprFilterCnt = 0;
@@ -13256,7 +13326,9 @@ const mainInit = () => {
13256
13326
  }
13257
13327
 
13258
13328
  // 画面揺れの設定
13259
- g_shakingFunc.get(g_stateObj.shaking)();
13329
+ if (g_scoreObj.baseFrame % 2 === 0) {
13330
+ g_shakingFunc.get(g_stateObj.shaking)();
13331
+ }
13260
13332
 
13261
13333
  // ユーザカスタムイベント(フレーム毎)
13262
13334
  g_customJsObj.mainEnterFrame.forEach(func => func());
@@ -13709,52 +13781,81 @@ const appearKeyTypes = (_j, _targets, _alphas = fillArray(_targets.length, 1)) =
13709
13781
  };
13710
13782
 
13711
13783
  /**
13712
- * FrzReturnの追加処理
13713
- * @param {number} _rad 回転角度
13714
- * @param {number[]} _axis 回転軸
13784
+ * FrzReturnの開始条件
13715
13785
  */
13716
- const changeReturn = (_rad, _axis) => {
13786
+ const startFrzReturn = () => {
13787
+ if (!g_workObj.frzReturnFlg) {
13788
+ if (g_workObj.frzReturnTimerId) {
13789
+ clearTimeout(g_workObj.frzReturnTimerId);
13790
+ g_workObj.frzReturnTimerId = null;
13791
+ }
13792
+ const seqLen = g_workObj.frzReturnSeq.length;
13793
+ executeFrzReturn(
13794
+ g_workObj.frzReturnSeq[seqLen > 1 ? Math.floor(Math.random() * seqLen) : 0], 0,
13795
+ g_frzReturnFunc.get(g_stateObj.frzReturn)()
13796
+ );
13797
+ }
13798
+ };
13799
+
13800
+ /**
13801
+ * FrzReturnの実行
13802
+ * @param {number[]} _seq FrzReturnの移動配列
13803
+ * @param {number} _idx FrzReturnの移動配列のインディクス(transformの決定に利用)
13804
+ * @param {number[]} _axis 回転軸(X, Y, X-Yなど)
13805
+ */
13806
+ const executeFrzReturn = (_seq, _idx, _axis) => {
13807
+
13808
+ if (!_seq || _idx >= _seq.length) {
13809
+ // 移動終了時
13810
+ delTransform(`mainSprite`, `frzReturn`);
13811
+ g_workObj.frzReturnFlg = false;
13812
+ g_workObj.frzReturnTimerId = null;
13813
+ return;
13814
+ }
13815
+ const sprite = document.getElementById(`mainSprite`);
13816
+ if (sprite === null) {
13817
+ // 画面がプレイ画面から移動した場合
13818
+ g_workObj.frzReturnFlg = false;
13819
+ g_workObj.frzReturnTimerId = null;
13820
+ return;
13821
+ }
13822
+
13717
13823
  g_workObj.frzReturnFlg = true;
13824
+ const _rad = _seq[_idx];
13825
+
13718
13826
  let _transform = `rotate${_axis[0]}(${_rad}deg)`;
13719
13827
  if (_axis[1] !== undefined) {
13720
13828
  _transform += ` rotate${_axis[1]}(${_rad}deg)`;
13721
13829
  }
13722
- const sprite = document.getElementById(`mainSprite`);
13723
- if (sprite !== null) {
13724
- sprite.style.transformStyle = `preserve-3d`;
13725
- const rad360 = _rad % 360;
13726
13830
 
13727
- let isBack = false;
13831
+ sprite.style.transformStyle = `preserve-3d`;
13832
+ const rad360 = ((_rad % 360) + 360) % 360;
13728
13833
 
13729
- // 単軸回転
13730
- if (_axis.length === 1) {
13731
- const axis = _axis[0];
13732
- if (axis === 'Y' || axis === 'X') {
13733
- isBack = rad360 > 90 && rad360 < 270;
13734
- }
13735
- // Z軸は平面回転なので「裏側」は存在しない
13736
- }
13834
+ let isBack = false;
13737
13835
 
13738
- // 2軸回転(XZ / XY / YZ)
13739
- if (_axis.length === 2) {
13740
- // 2軸回転は「どちらかの軸が裏側なら裏側」とみなす
13741
- const [a1, a2] = _axis;
13742
- const back1 = (a1 === 'Y' || a1 === 'X') && (rad360 > 90 && rad360 < 270);
13743
- const back2 = (a2 === 'Y' || a2 === 'X') && (rad360 > 90 && rad360 < 270);
13744
- isBack = back1 || back2;
13836
+ // 単軸回転
13837
+ if (_axis.length === 1) {
13838
+ const axis = _axis[0];
13839
+ if (axis === 'Y' || axis === 'X') {
13840
+ isBack = rad360 > 90 && rad360 < 270;
13745
13841
  }
13746
- sprite.style.opacity = isBack ? 0.7 : 1;
13747
-
13748
- addTransform(`mainSprite`, `frzReturn`, _transform, g_transPriority.frzReturn);
13842
+ // Z軸は平面回転なので「裏側」は存在しない
13843
+ }
13749
13844
 
13750
- if (_rad < 360 && g_workObj.frzReturnFlg) {
13751
- setTimeout(() => changeReturn(_rad + 4, _axis), 20);
13752
- } else {
13753
- delTransform(`mainSprite`, `frzReturn`);
13754
- g_workObj.frzReturnFlg = false;
13755
- }
13845
+ // 2軸回転(XZ / XY / YZ)
13846
+ if (_axis.length === 2) {
13847
+ // 2軸回転は「どちらかの軸が裏側なら裏側」とみなす
13848
+ const [a1, a2] = _axis;
13849
+ const back1 = (a1 === 'Y' || a1 === 'X') && (rad360 > 90 && rad360 < 270);
13850
+ const back2 = (a2 === 'Y' || a2 === 'X') && (rad360 > 90 && rad360 < 270);
13851
+ isBack = back1 || back2;
13756
13852
  }
13757
- }
13853
+ sprite.style.opacity = isBack ? 0.7 : 1;
13854
+
13855
+ addTransform(`mainSprite`, `frzReturn`, _transform, g_transPriority.frzReturn);
13856
+
13857
+ g_workObj.frzReturnTimerId = setTimeout(() => executeFrzReturn(_seq, _idx + 1, _axis), 20);
13858
+ };
13758
13859
 
13759
13860
  /**
13760
13861
  * AutoRetryの設定
@@ -13946,9 +14047,7 @@ const changeHitFrz = (_j, _k, _name, _difFrame = 0) => {
13946
14047
 
13947
14048
  // FrzReturnの設定
13948
14049
  if (g_stateObj.frzReturn !== C_FLG_OFF) {
13949
- if (!g_workObj.frzReturnFlg) {
13950
- changeReturn(4, g_frzReturnFunc.get(g_stateObj.frzReturn)());
13951
- }
14050
+ startFrzReturn();
13952
14051
  }
13953
14052
  g_customJsObj[`judg_${_name}Hit`].forEach(func => func(_difFrame));
13954
14053
  };
@@ -13971,9 +14070,7 @@ const changeFailedFrz = (_j, _k) => {
13971
14070
 
13972
14071
  // FrzReturnの設定
13973
14072
  if (g_stateObj.frzReturn !== C_FLG_OFF) {
13974
- if (!g_workObj.frzReturnFlg) {
13975
- changeReturn(4, g_frzReturnFunc.get(g_stateObj.frzReturn)());
13976
- }
14073
+ startFrzReturn();
13977
14074
  }
13978
14075
  };
13979
14076
 
@@ -14192,10 +14289,8 @@ const judgeRecovery = (_name, _difFrame) => {
14192
14289
  lifeRecovery();
14193
14290
  finishViewing();
14194
14291
 
14195
- if (g_stateObj.freezeReturn !== C_FLG_OFF) {
14196
- if ((g_resultObj.ii + g_resultObj.shakin) % 100 === 0 && !g_workObj.frzReturnFlg) {
14197
- changeReturn(1, g_frzReturnFunc.get(g_stateObj.frzReturn)());
14198
- }
14292
+ if (g_stateObj.frzReturn !== C_FLG_OFF && (g_resultObj.ii + g_resultObj.shakin) % 100 === 0) {
14293
+ startFrzReturn();
14199
14294
  }
14200
14295
  if (_name === `shakin`) {
14201
14296
  quickRetry(`Shakin(Great)`);
@@ -14571,9 +14666,9 @@ const resultInit = () => {
14571
14666
  maxCombo: 0, fmaxCombo: 0, score: 0,
14572
14667
  };
14573
14668
 
14574
- const highscoreCondition = (g_stateObj.autoAll === C_FLG_OFF && g_headerObj.playbackRate === 1 &&
14575
- (g_stateObj.shuffle === C_FLG_OFF || (mirrorName !== `` && orgShuffleFlg)));
14576
- if (highscoreCondition) {
14669
+ const highscorePreCondition = (g_stateObj.autoAll === C_FLG_OFF && g_headerObj.playbackRate === 1 &&
14670
+ (g_stateObj.shuffle === C_FLG_OFF || (g_stateObj.shuffle.endsWith(`Mirror`) && orgShuffleFlg)));
14671
+ if (highscorePreCondition) {
14577
14672
 
14578
14673
  // ハイスコア差分描画
14579
14674
  Object.keys(jdgScoreObj).filter(score => score !== `score`).forEach(score =>
@@ -14748,7 +14843,7 @@ const resultInit = () => {
14748
14843
  const currentDateTime = new Date().toLocaleString();
14749
14844
  g_customJsObj.result.forEach(func => func());
14750
14845
 
14751
- if (highscoreCondition) {
14846
+ if (highscorePreCondition) {
14752
14847
 
14753
14848
  // 古いキー定義の情報を検索
14754
14849
  const relatedKeys = Object.entries(g_keyObj.keyTransPattern)
@@ -14941,7 +15036,7 @@ const resultInit = () => {
14941
15036
  drawText(g_resultObj[score], { x: 200, hy: 7 + jdgScoreObj[score].pos, align: C_ALIGN_RIGHT });
14942
15037
  });
14943
15038
 
14944
- if (highscoreCondition) {
15039
+ if (highscorePreCondition) {
14945
15040
  drawText(`(${highscoreDfObj.score >= 0 ? '+' : '-'} ${Math.abs(highscoreDfObj.score)})`,
14946
15041
  { x: 206, hy: 18, color: highscoreDfObj.score > 0 ? `#ffff99` : `#cccccc`, align: C_ALIGN_RIGHT });
14947
15042
  }
@@ -15170,14 +15265,16 @@ const getSelectedSettingList = (_shuffleName) => {
15170
15265
  withOptions(g_stateObj.appearance, `Visible`) +
15171
15266
  ((g_appearanceRanges.includes(g_stateObj.appearance) && g_stateObj.filterLock === C_FLG_ON) ? `(${g_hidSudObj.filterPos}%)` : ``),
15172
15267
  withOptions(g_stateObj.gauge, g_settings.gauges[0]),
15173
- withOptions(g_stateObj.playWindow, `Default`),
15268
+ withOptions(g_stateObj.playWindow, `Default`,
15269
+ `${getStgDetailName(g_stateObj.playWindowType === `Reverse` ? `R-` : ``)}${getStgDetailName(g_stateObj.playWindow)}`),
15174
15270
  withOptions(g_stateObj.stepArea, `Default`),
15175
- withOptions(g_stateObj.frzReturn, C_FLG_OFF, `FR:${g_stateObj.frzReturn}`),
15271
+ withOptions(g_stateObj.frzReturn, C_FLG_OFF,
15272
+ `FR:${getStgDetailName(g_stateObj.frzReturn)}(${getStgDetailName(g_stateObj.frzReturnType)})`),
15176
15273
  withOptions(g_stateObj.shaking, C_FLG_OFF),
15177
15274
  withOptions(g_stateObj.effect, C_FLG_OFF),
15178
- withOptions(g_stateObj.camoufrage, C_FLG_OFF, `Cmf:${g_stateObj.camoufrage}`),
15179
- withOptions(g_stateObj.swapping, C_FLG_OFF, `Swap:${g_stateObj.swapping}`),
15180
- withOptions(g_stateObj.judgRange, `Normal`, `Judg:${g_stateObj.judgRange}`),
15275
+ withOptions(g_stateObj.camoufrage, C_FLG_OFF, `Cmf:${getStgDetailName(g_stateObj.camoufrage)}`),
15276
+ withOptions(g_stateObj.swapping, C_FLG_OFF, `Swap:${getStgDetailName(g_stateObj.swapping)}`),
15277
+ withOptions(g_stateObj.judgRange, `Normal`, `Judg:${getStgDetailName(g_stateObj.judgRange)}`),
15181
15278
  ].filter(value => value !== ``).join(`, `);
15182
15279
 
15183
15280
  // Display設定の組み立て処理 (Ex: Step : FlatBar, Judge, Life : OFF)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/03/02 (v45.3.1)
8
+ * Revised : 2026/03/05 (v45.5.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -51,6 +51,9 @@ const g_limitObj = {
51
51
  setLblHeight: 22,
52
52
  setLblSiz: 17,
53
53
 
54
+ setLblLeftShort: 250,
55
+ setLblWidthShort: 120,
56
+
54
57
  // 設定画面の左右移動ボタンの幅、フォントサイズ
55
58
  setMiniWidth: 40,
56
59
  setMiniSiz: 18,
@@ -1164,8 +1167,10 @@ const g_stateObj = {
1164
1167
  opacity: 100,
1165
1168
 
1166
1169
  playWindow: `Default`,
1170
+ playWindowType: `---`,
1167
1171
  stepArea: `Default`,
1168
1172
  frzReturn: C_FLG_OFF,
1173
+ frzReturnType: `360deg`,
1169
1174
  shaking: C_FLG_OFF,
1170
1175
  effect: C_FLG_OFF,
1171
1176
  camoufrage: C_FLG_OFF,
@@ -1330,9 +1335,12 @@ const g_settings = {
1330
1335
  special: 0,
1331
1336
  },
1332
1337
 
1333
- playWindows: [`Default`, `Stairs`, `R-Stairs`, `Slope`, `R-Slope`, `Distorted`, `R-Distorted`, `SideScroll`, `R-SideScroll`],
1338
+ playWindows: [`Default`, `Stairs`, `Slope`, `Distorted`, `SideScroll`],
1334
1339
  playWindowNum: 0,
1335
1340
 
1341
+ playWindowTypes: [`---`, `Reverse`],
1342
+ playWindowTypeNum: 0,
1343
+
1336
1344
  stepAreas: [`Default`, `Halfway`, `2Step`, `Mismatched`, `R-Mismatched`, `X-Flower`, `Alt-Crossing`],
1337
1345
  stepAreaLayers: [`2Step`, `Mismatched`, `R-Mismatched`, `X-Flower`, `Alt-Crossing`],
1338
1346
  stepAreaNum: 0,
@@ -1340,7 +1348,10 @@ const g_settings = {
1340
1348
  frzReturns: [C_FLG_OFF, `X-Axis`, `Y-Axis`, `Z-Axis`, `Random`, `XY-Axis`, `XZ-Axis`, `YZ-Axis`, `Random+`],
1341
1349
  frzReturnNum: 0,
1342
1350
 
1343
- shakings: [C_FLG_OFF, `Horizontal`, `Vertical`, `X-Horizontal`, `X-Vertical`, `Drunk`, `S-Drunk`],
1351
+ frzReturnTypes: [`360deg`, `120deg`, `60deg`, `±360deg`, `±120deg`, `Pendulum`],
1352
+ frzReturnTypeNum: 0,
1353
+
1354
+ shakings: [C_FLG_OFF, `Horizontal`, `Vertical`, `X-Horizontal`, `X-Vertical`, `Drunk`, `S-Drunk`, `H-Drunk`],
1344
1355
  shakingNum: 0,
1345
1356
 
1346
1357
  effects: [C_FLG_OFF, `Dizzy`, `Spin`, `Wave`, `Storm`, `Blinking`, `Squids`],
@@ -1394,7 +1405,9 @@ const g_transPriority = {
1394
1405
  playWindow: 100,
1395
1406
  stepArea: 110,
1396
1407
  frzReturn: 120,
1397
- shaking: 130,
1408
+ shakingR: 130,
1409
+ shakingX: 140,
1410
+ shakingY: 150,
1398
1411
  scale: 200,
1399
1412
  };
1400
1413
 
@@ -1589,6 +1602,7 @@ const resetXY = () => {
1589
1602
 
1590
1603
  /**
1591
1604
  * データ消去用管理関数
1605
+ * - 対応するキー名: g_settings.dataMgtNum で定義したキー
1592
1606
  */
1593
1607
  const g_resetFunc = new Map([
1594
1608
  ['highscores', () => {
@@ -1638,6 +1652,7 @@ const g_storageFunc = new Map([
1638
1652
 
1639
1653
  /**
1640
1654
  * シャッフル適用関数
1655
+ * - 対応するキー名: g_settings.shuffles
1641
1656
  * @param {number} keyNum
1642
1657
  * @param {array} shuffleGroup
1643
1658
  */
@@ -1662,6 +1677,7 @@ const g_shuffleFunc = new Map([
1662
1677
 
1663
1678
  /**
1664
1679
  * モーション適用関数
1680
+ * - 対応するキー名: g_settings.motions
1665
1681
  * @param {array} frms フレーム別の速度設定用配列。配列の15がステップゾーン上、0~14は矢印の枠外管理用
1666
1682
  */
1667
1683
  const g_motionFunc = new Map([
@@ -1676,6 +1692,7 @@ const g_motionFunc = new Map([
1676
1692
 
1677
1693
  /**
1678
1694
  * モーション適用中のアルファ値制御関数
1695
+ * - 対応するキー名: g_settings.motions
1679
1696
  * @param {object} _obj 対象オブジェクト
1680
1697
  * @param {object} _property 対象オブジェクトのプロパティ情報 (g_attrObj[オブジェクト名])
1681
1698
  */
@@ -1700,24 +1717,23 @@ const motionAlphaToggle = (_obj, _property) => {
1700
1717
 
1701
1718
  /**
1702
1719
  * PlayWindow適用関数
1720
+ * - 対応するキー名: g_settings.playWindows
1703
1721
  */
1704
- const g_changeStairs = (_rad) => `rotate(${_rad}deg)`;
1705
- const g_changeSkew = (_rad) => `Skew(${_rad}deg, ${_rad}deg) scaleY(0.9)`;
1722
+ const g_playWindowDir = () => g_stateObj.playWindowType === `Reverse` ? 1 : -1;
1723
+ const g_changeStairs = (_rad) => `rotate(${_rad * g_playWindowDir()}deg)`;
1724
+ const g_changeSkew = (_rad) => `Skew(${_rad * g_playWindowDir()}deg, ${_rad * g_playWindowDir()}deg) scaleY(0.9)`;
1706
1725
 
1707
1726
  const g_playWindowFunc = new Map([
1708
1727
  ['Default', () => ``],
1709
- ['Stairs', () => g_changeStairs(-8)],
1710
- ['R-Stairs', () => g_changeStairs(8)],
1711
- ['Slope', () => g_changeStairs(-g_slopeAngle())],
1712
- ['R-Slope', () => g_changeStairs(g_slopeAngle())],
1713
- ['Distorted', () => g_changeSkew(-15)],
1714
- ['R-Distorted', () => g_changeSkew(15)],
1715
- ['SideScroll', () => g_changeStairs(-90)],
1716
- ['R-SideScroll', () => g_changeStairs(90)],
1728
+ ['Stairs', () => g_changeStairs(8)],
1729
+ ['Slope', () => g_changeStairs(g_slopeAngle())],
1730
+ ['Distorted', () => g_changeSkew(15)],
1731
+ ['SideScroll', () => g_changeStairs(90)],
1717
1732
  ]);
1718
1733
 
1719
1734
  /**
1720
1735
  * StepArea適用関数
1736
+ * - 対応するキー名: g_settings.stepAreas
1721
1737
  */
1722
1738
  const g_arrowGroupSprite = [`stepSprite`, `arrowSprite`, `frzHitSprite`];
1723
1739
  const halfwayOffset = _j => (_j % 2 === 0 ? 1 : -1) * (g_headerObj.playingHeight / 2 - g_posObj.stepY + (g_posObj.stepYR - C_ARW_WIDTH) / 2);
@@ -1777,62 +1793,87 @@ const g_stepAreaFunc = new Map([
1777
1793
 
1778
1794
  /**
1779
1795
  * Shaking適用関数
1796
+ * - 対応するキー名: g_settings.shakings
1797
+ * - Drunk系は補正座標が0になったときに判定を行い、移動方向や回転を切り替える
1780
1798
  */
1781
1799
  const getShakingDist = () => (Math.abs((g_scoreObj.baseFrame / 2) % 100 - 50) - 25);
1782
1800
  const g_shakingFunc = new Map([
1783
1801
  ['OFF', () => true],
1784
- ['Horizontal', () => {
1785
- if (g_scoreObj.baseFrame % 2 === 0)
1786
- addTransform(`mainSprite`, `shakingX`, `translateX(${getShakingDist()}px)`, g_transPriority.shaking)
1802
+ ['Horizontal', (_multi = 1) => {
1803
+ addTransform(`mainSprite`, `shakingX_base`, `translateX(${getShakingDist() * _multi}px)`, g_transPriority.shakingX)
1787
1804
  }],
1788
- ['Vertical', () => {
1789
- if (g_scoreObj.baseFrame % 2 === 0)
1790
- addTransform(`mainSprite`, `shakingY`, `translateY(${getShakingDist() / 2}px)`, g_transPriority.shaking)
1805
+ ['Vertical', (_multi = 1) => {
1806
+ addTransform(`mainSprite`, `shakingY_base`, `translateY(${getShakingDist() / 2 * _multi}px)`, g_transPriority.shakingY)
1791
1807
  }],
1792
- ['X-Horizontal', () => {
1793
- if (g_scoreObj.baseFrame % 2 === 0)
1794
- for (let j = 0; j < g_stateObj.layerNum; j++) {
1795
- addTransform(`mainSprite${j}`, `shakingX`, `translateX(${getDirFromLayer(j) * (4 / 3) * getShakingDist()}px)`, g_transPriority.shaking);
1796
- }
1808
+ ['X-Horizontal', (_multi = 1) => {
1809
+ for (let j = 0; j < g_stateObj.layerNum; j++) {
1810
+ addTransform(`mainSprite${j}`, `shakingX_layer`, `translateX(${getDirFromLayer(j) * (4 / 3) * getShakingDist() * _multi}px)`, g_transPriority.shakingX);
1811
+ }
1797
1812
  }],
1798
- ['X-Vertical', () => {
1799
- if (g_scoreObj.baseFrame % 2 === 0)
1800
- for (let j = 0; j < g_stateObj.layerNum; j++) {
1801
- addTransform(`mainSprite${j}`, `shakingY`, `translateY(${getDirFromLayer(j) * getShakingDist()}px)`, g_transPriority.shaking);
1802
- }
1813
+ ['X-Vertical', (_multi = 1) => {
1814
+ for (let j = 0; j < g_stateObj.layerNum; j++) {
1815
+ addTransform(`mainSprite${j}`, `shakingY_layer`, `translateY(${getDirFromLayer(j) * getShakingDist() * _multi}px)`, g_transPriority.shakingY);
1816
+ }
1803
1817
  }],
1804
- ['Drunk', () => {
1805
- if (g_scoreObj.baseFrame % 2 === 0) {
1806
- // Drunkは揺れの軸が途中で変わるため、基準位置取得のためにmainSpriteのみaddX, addYを使用
1807
- const shakeX = g_posXs.mainSprite?.get(`shakingX`) ?? 0;
1808
- const shakeY = g_posYs.mainSprite?.get(`shakingY`) ?? 0;
1809
- if (shakeX === 0 && shakeY === 0) {
1810
- g_workObj.drunkXFlg = Math.random() < 0.5;
1811
- g_workObj.drunkYFlg = Math.random() < 0.5;
1812
- }
1813
- if (g_workObj.drunkXFlg) {
1814
- const deltaX = getShakingDist();
1815
- addX(`mainSprite`, `shakingX`, deltaX, { priority: g_transPriority.shaking });
1816
- addTransform(`infoSprite`, `shakingX`, `translateX(${deltaX}px)`, g_transPriority.shaking);
1817
- addTransform(`judgeSprite`, `shakingX`, `translateX(${deltaX}px)`, g_transPriority.shaking);
1818
- }
1819
- if (g_workObj.drunkYFlg) {
1820
- const deltaY = getShakingDist() / 2;
1821
- addY(`mainSprite`, `shakingY`, deltaY, { priority: g_transPriority.shaking });
1822
- addTransform(`infoSprite`, `shakingY`, `translateY(${deltaY}px)`, g_transPriority.shaking);
1823
- addTransform(`judgeSprite`, `shakingY`, `translateY(${deltaY}px)`, g_transPriority.shaking);
1818
+ ['Drunk', (_multi = 1) => {
1819
+ const dist = getShakingDist();
1820
+ if (g_workObj.drunkXFlg) {
1821
+ const deltaX = dist * _multi;
1822
+ addTransform(`mainSprite`, `shakingX_drunk`, `translateX(${deltaX}px)`, g_transPriority.shakingX);
1823
+ addTransform(`infoSprite`, `shakingX_drunk`, `translateX(${deltaX}px)`, g_transPriority.shakingX);
1824
+ addTransform(`judgeSprite`, `shakingX_drunk`, `translateX(${deltaX}px)`, g_transPriority.shakingX);
1825
+ }
1826
+ if (g_workObj.drunkYFlg) {
1827
+ const deltaY = dist / 2 * _multi;
1828
+ addTransform(`mainSprite`, `shakingY_drunk`, `translateY(${deltaY}px)`, g_transPriority.shakingY);
1829
+ addTransform(`infoSprite`, `shakingY_drunk`, `translateY(${deltaY}px)`, g_transPriority.shakingY);
1830
+ addTransform(`judgeSprite`, `shakingY_drunk`, `translateY(${deltaY}px)`, g_transPriority.shakingY);
1831
+ }
1832
+ // 補正がゼロになったときに軸の移動方法をランダムで決定
1833
+ if (dist === 0) {
1834
+ g_workObj.drunkXFlg = Math.random() < 0.5;
1835
+ g_workObj.drunkYFlg = Math.random() < 0.5;
1836
+
1837
+ if (!g_workObj.drunkXFlg && !g_workObj.drunkYFlg) {
1838
+ g_workObj.drunkYFlg = true;
1824
1839
  }
1825
1840
  }
1826
1841
  }],
1827
1842
  ['S-Drunk', () => {
1828
- if (g_scoreObj.baseFrame % 2 === 0) {
1829
- g_shakingFunc.get(`Drunk`)();
1830
- if (g_workObj.drunkXFlg) {
1831
- g_shakingFunc.get(`X-Vertical`)();
1832
- }
1833
- if (g_workObj.drunkYFlg) {
1834
- g_shakingFunc.get(`X-Horizontal`)();
1835
- }
1843
+ // Drunkとはあえて異なる軸の補正を掛ける
1844
+ if (g_workObj.drunkXFlg) {
1845
+ g_shakingFunc.get(`X-Vertical`)(2);
1846
+ }
1847
+ if (g_workObj.drunkYFlg) {
1848
+ g_shakingFunc.get(`X-Horizontal`)(2);
1849
+ }
1850
+ g_shakingFunc.get(`Drunk`)(2);
1851
+ }],
1852
+ ['H-Drunk', () => {
1853
+ const dist = getShakingDist();
1854
+
1855
+ // X方向、Y方向の移動方法。S-Drunkと同様、Drunkとあえて異なる軸の補正を掛ける
1856
+ // 本来は適用するtransform先が異なるためdelTransformを行う必要があるが、補正ゼロ時に切り替えるため問題なし
1857
+ if (g_workObj.drunkXFlg) {
1858
+ g_shakingFunc.get((g_workObj.drunkAxisFlg ? `X-` : ``) + `Vertical`)(3);
1859
+ }
1860
+ if (g_workObj.drunkYFlg) {
1861
+ g_shakingFunc.get((g_workObj.drunkAxisFlg ? `X-` : ``) + `Horizontal`)(3);
1862
+ }
1863
+ // 軸回転の設定(判定・メイン部分は常時回転、メイン内の各層は条件式により回転するかどうかを決定)
1864
+ for (let j = 0; j < g_stateObj.layerNum; j++) {
1865
+ g_workObj.drunkRotateFlg
1866
+ ? addTransform(`mainSprite${j}`, `shakingR_layer`, `rotate(${getDirFromLayer(j) * dist}deg)`, g_transPriority.shakingR)
1867
+ : delTransform(`mainSprite${j}`, `shakingR_layer`);
1868
+ }
1869
+ addTransform(`mainSprite`, `shakingR_base`, `rotate(${dist / 2}deg)`, g_transPriority.shakingR);
1870
+ addTransform(`infoSprite`, `shakingR_base`, `rotate(${dist / 2}deg)`, g_transPriority.shakingR);
1871
+
1872
+ g_shakingFunc.get(`Drunk`)(2);
1873
+ if (dist === 0) {
1874
+ // 補正がゼロになったときに軸の移動方法と回転方法をランダムで決定
1875
+ g_workObj.drunkAxisFlg = Math.random() >= 0.33;
1876
+ g_workObj.drunkRotateFlg = Math.random() >= 0.66;
1836
1877
  }
1837
1878
  }],
1838
1879
  ]);
@@ -1858,6 +1899,7 @@ const g_getSecondaryAxis = (_primaryAxis) => {
1858
1899
 
1859
1900
  /**
1860
1901
  * FrzReturn適用関数
1902
+ * - 対応するキー名: g_settings.frzReturns
1861
1903
  */
1862
1904
  const g_frzReturnFunc = new Map([
1863
1905
  ['OFF', () => true],
@@ -1875,6 +1917,91 @@ const g_frzReturnFunc = new Map([
1875
1917
  }],
1876
1918
  ]);
1877
1919
 
1920
+ /**
1921
+ * FrzReturnの種別ごとの移動配列を作成
1922
+ * - 対応するキー名: g_settings.frzReturnTypes
1923
+ * - キー: FrzReturn種別 (例: "60deg", "±120deg")
1924
+ * - 値: 移動配列を返す関数 (オプション引数 _dir で方向指定、デフォルト 1)
1925
+ * @type {Map<string, (dir?: number) => number[][]>}
1926
+ */
1927
+ const g_frzReturnSeqFunc = new Map([
1928
+ [`60deg`, (_dir = 1) => {
1929
+ const steps = 25;
1930
+ return [
1931
+ [
1932
+ ...makeEaseSequence(0, 60 * _dir, steps, easeInOutQuad),
1933
+ ...makeEaseSequence(60 * _dir, 0, steps, easeInOutQuad),
1934
+ ],
1935
+ ];
1936
+ }],
1937
+ [`120deg`, (_dir = 1) => {
1938
+ const steps = 40;
1939
+ return [
1940
+ [
1941
+ ...makeEaseSequence(0, 120 * _dir, steps, easeInOutQuad),
1942
+ ...makeEaseSequence(120 * _dir, 0, steps, easeInOutQuad),
1943
+ ],
1944
+ ];
1945
+ }],
1946
+ [`360deg`, (_dir = 1) => {
1947
+ return [
1948
+ Array.from({ length: 91 }, (_, i) => i * 4 * _dir)
1949
+ ];
1950
+ }],
1951
+ [`Pendulum`, (_dir = 1) => {
1952
+ const steps = 25;
1953
+ return [
1954
+ [
1955
+ ...makeEaseSequence(0, -60 * _dir, steps, easeInOutQuad),
1956
+ ...makeEaseSequence(-60 * _dir, 60 * _dir, steps * 2, easeInOutQuad),
1957
+ ...makeEaseSequence(60 * _dir, 0, steps, easeInOutQuad),
1958
+ ],
1959
+ [
1960
+ ...makeEaseSequence(0, -70 * _dir, steps, easeInOutQuad),
1961
+ ...makeEaseSequence(-70 * _dir, 70 * _dir, steps * 2, easeInOutQuad),
1962
+ ...makeEaseSequence(70 * _dir, 0, steps, easeInOutQuad),
1963
+ ],
1964
+ [
1965
+ ...makeEaseSequence(0, -80 * _dir, steps, easeInOutQuad),
1966
+ ...makeEaseSequence(-80 * _dir, 80 * _dir, steps * 2, easeInOutQuad),
1967
+ ...makeEaseSequence(80 * _dir, 0, steps, easeInOutQuad),
1968
+ ],
1969
+ ];
1970
+ }],
1971
+ [`±120deg`, () => g_frzReturnSeqFunc.get(`120deg`)().concat(g_frzReturnSeqFunc.get(`120deg`)(-1))],
1972
+ [`±360deg`, () => g_frzReturnSeqFunc.get(`360deg`)().concat(g_frzReturnSeqFunc.get(`360deg`)(-1))],
1973
+ ]);
1974
+
1975
+ /**
1976
+ * イージング作成関数
1977
+ * @param {(t: number) => number} _t
1978
+ * @returns {number}
1979
+ */
1980
+ const easeInOutQuad = _t => _t < 0.5
1981
+ ? 2 * _t * _t
1982
+ : 1 - Math.pow(-2 * _t + 2, 2) / 2;
1983
+
1984
+ /**
1985
+ * イージング用の移動配列の作成
1986
+ * @param {number} _start
1987
+ * @param {number} _end
1988
+ * @param {number} _steps
1989
+ * @param {number} _easing
1990
+ * @returns {number[]}
1991
+ */
1992
+ const makeEaseSequence = (_start, _end, _steps, _easing) => {
1993
+ if (_steps <= 0) {
1994
+ return [_start];
1995
+ }
1996
+ const seq = [];
1997
+ for (let i = 0; i <= _steps; i++) {
1998
+ const t = i / _steps;
1999
+ const e = _easing(t);
2000
+ seq.push(_start + (_end - _start) * e);
2001
+ }
2002
+ return seq;
2003
+ };
2004
+
1878
2005
  /**
1879
2006
  * Effect適用関数
1880
2007
  * @param {string} _arrowEffect
@@ -1893,6 +2020,10 @@ const g_setEffect = (_arrowEffect, _frzEffect = ``, _frzArrowEffect = _arrowEffe
1893
2020
  }
1894
2021
  }
1895
2022
  };
2023
+ /**
2024
+ * Effect定義関数
2025
+ * - 対応するキー名: g_settings.effects
2026
+ */
1896
2027
  const g_effectFunc = new Map([
1897
2028
  ['OFF', () => true],
1898
2029
  ['Dizzy', () => g_setEffect(`effects-dizzy`)],
@@ -2373,6 +2504,7 @@ const g_shortcutObj = {
2373
2504
  Numpad0: { id: `btnPrecond9` },
2374
2505
  Escape: { id: `btnBack` },
2375
2506
  ShiftLeft_Tab: { id: `btnBack` },
2507
+ ShiftRight_Tab: { id: `btnBack` },
2376
2508
  },
2377
2509
  option: {
2378
2510
  ShiftLeft_KeyD: { id: `lnkDifficultyL` },
@@ -2622,18 +2754,29 @@ const g_shortcutObj = {
2622
2754
  },
2623
2755
  exSetting: {
2624
2756
  ShiftLeft_KeyP: { id: `lnkPlayWindowL` },
2757
+ ShiftRight_KeyP: { id: `lnkPlayWindowL` },
2625
2758
  ShiftLeft_KeyS: { id: `lnkStepAreaL` },
2759
+ ShiftRight_KeyS: { id: `lnkStepAreaL` },
2626
2760
  ShiftLeft_KeyF: { id: `lnkFrzReturnL` },
2761
+ ShiftRight_KeyF: { id: `lnkFrzReturnL` },
2627
2762
  ShiftLeft_KeyH: { id: `lnkShakingL` },
2763
+ ShiftRight_KeyH: { id: `lnkShakingL` },
2628
2764
  ShiftLeft_KeyE: { id: `lnkEffectL` },
2765
+ ShiftRight_KeyE: { id: `lnkEffectL` },
2629
2766
  ShiftLeft_KeyC: { id: `lnkCamoufrageL` },
2767
+ ShiftRight_KeyC: { id: `lnkCamoufrageL` },
2630
2768
  ShiftLeft_KeyW: { id: `lnkSwappingL` },
2769
+ ShiftRight_KeyW: { id: `lnkSwappingL` },
2631
2770
  ShiftLeft_KeyJ: { id: `lnkJudgRangeL` },
2771
+ ShiftRight_KeyJ: { id: `lnkJudgRangeL` },
2632
2772
  ShiftLeft_KeyA: { id: `lnkAutoRetryL` },
2773
+ ShiftRight_KeyA: { id: `lnkAutoRetryL` },
2633
2774
 
2634
2775
  KeyP: { id: `lnkPlayWindowR` },
2776
+ KeyR: { id: `lnkPlayWindowType` },
2635
2777
  KeyS: { id: `lnkStepAreaR` },
2636
2778
  KeyF: { id: `lnkFrzReturnR` },
2779
+ KeyD: { id: `lnkFrzReturnType` },
2637
2780
  KeyH: { id: `lnkShakingR` },
2638
2781
  KeyE: { id: `lnkEffectR` },
2639
2782
  KeyC: { id: `lnkCamoufrageR` },
@@ -4210,6 +4353,7 @@ const g_lblNameObj = {
4210
4353
  'u_Asymmetry': `Asymmetry`,
4211
4354
  'u_Flat': `Flat`,
4212
4355
  'u_R-': `R-`,
4356
+ 'u_---': `---`,
4213
4357
  'u_Reverse': `Reverse`,
4214
4358
 
4215
4359
  'u_Mirror': `Mirror`,
@@ -4250,13 +4394,9 @@ const g_lblNameObj = {
4250
4394
  'u_Hid&Sud+': `Hid&Sud+`,
4251
4395
 
4252
4396
  'u_Stairs': `Stairs`,
4253
- 'u_R-Stairs': `R-Stairs`,
4254
4397
  'u_Slope': `Slope`,
4255
- 'u_R-Slope': `R-Slope`,
4256
4398
  'u_Distorted': `Distorted`,
4257
- 'u_R-Distorted': `R-Distorted`,
4258
4399
  'u_SideScroll': `SideScroll`,
4259
- 'u_R-SideScroll': `R-SideScroll`,
4260
4400
 
4261
4401
  'u_Halfway': `Halfway`,
4262
4402
  'u_2Step': `2Step`,
@@ -4278,6 +4418,7 @@ const g_lblNameObj = {
4278
4418
  'u_X-Vertical': `X-Vertical`,
4279
4419
  'u_Drunk': `Drunk`,
4280
4420
  'u_S-Drunk': `S-Drunk`,
4421
+ 'u_H-Drunk': `H-Drunk`,
4281
4422
 
4282
4423
  'u_Dizzy': `Dizzy`,
4283
4424
  'u_Spin': `Spin`,
@@ -4298,7 +4439,7 @@ const g_lblNameObj = {
4298
4439
  'u_Shakin(Great)': `Shakin(Great)`,
4299
4440
  'u_Fast/Slow': `Fast/Slow`,
4300
4441
 
4301
- 'u_Velocity': `Velocity`,
4442
+ 'u_Speed': `Velocity`,
4302
4443
  'u_Density': `Density`,
4303
4444
  'u_ToolDif': `DifLevel`,
4304
4445
  'u_HighScore': `HighScore`,
@@ -4390,6 +4531,13 @@ const g_lang_lblNameObj = {
4390
4531
  s_printTitle: `Dancing☆Onigiri レベル計算ツール+++`,
4391
4532
  s_printHeader: `難易度\t同時\t縦連\t総数\t矢印\t氷矢印\tAPM\t時間`,
4392
4533
 
4534
+ 'u_60deg': `60°`,
4535
+ 'u_120deg': `120°`,
4536
+ 'u_360deg': `360°`,
4537
+ 'u_Pendulum': `Pendulum`,
4538
+ 'u_±120deg': `±120°`,
4539
+ 'u_±360deg': `±360°`,
4540
+
4393
4541
  j_ii: "(・∀・)イイ!!",
4394
4542
  j_shakin: "(`・ω・)シャキン",
4395
4543
  j_matari: "( ´∀`)マターリ",
@@ -4434,6 +4582,13 @@ const g_lang_lblNameObj = {
4434
4582
  s_printTitle: `Dancing☆Onigiri Level Calculator+++`,
4435
4583
  s_printHeader: `Level\tChords\tJack\tAll\tArrow\tFrz\tAPM\tTime`,
4436
4584
 
4585
+ 'u_60deg': `60deg`,
4586
+ 'u_120deg': `120deg`,
4587
+ 'u_360deg': `360deg`,
4588
+ 'u_Pendulum': `Pendulum`,
4589
+ 'u_±120deg': `±120deg`,
4590
+ 'u_±360deg': `±360deg`,
4591
+
4437
4592
  j_ii: ":D Perfect!!",
4438
4593
  j_shakin: ":) Great!",
4439
4594
  j_matari: ":| Good",
@@ -4521,13 +4676,16 @@ const g_lang_msgObj = {
4521
4676
 
4522
4677
  playWindow: `ステップゾーン及び矢印の位置を全体的に回転する等の設定です。\n[Stairs/Slope] ステップゾーンを階段状にします\n[Distorted] 画面を歪ませます\n` +
4523
4678
  `[SideScroll] 横スクロールモードになります`,
4679
+ playWindowType: `[Reverse] ステップゾーン及び矢印の位置について逆方向の回転が掛かります`,
4524
4680
  stepArea: `ステップゾーンの位置を変更します。\n[Halfway] ステップゾーンが中央に表示されます\n[2Step] ステップゾーンが2段に分かれて流れてきます\n` +
4525
4681
  `[Mismatched/R-Mismatched] スクロールの向きが上下で異なる方向に流れます\n` +
4526
4682
  `[X-Flower] レーンが花びらのように広がります\n[Alt-Crossing] レーンが交互に違う方向から流れます`,
4527
4683
  frzReturn: `フリーズアロー到達時及び矢印の回復判定が100の倍数に達するごとに、X/Y/Z軸のいずれかに回転します`,
4684
+ frzReturnType: `[360°/120°/60°] 指定の角度まで回転します\n[±360°/±120°] 360°/120°に加えて逆回転が掛かることがあります\n[Pendulum] 振り子のように左右に動きます`,
4528
4685
  shaking: `ステップゾーン及び矢印を揺らす設定です。\n[Horizontal] 横方向に揺らします\n[Vertical] 縦方向に揺らします\n` +
4529
4686
  `[X-Horizontal] レイヤーごとに左右交互の向きで横に揺らします\n[X-Vertical] レイヤーごとに上下交互の向きで縦に揺らします\n[Drunk] 画面全体を上下左右ランダムに揺らします。画面酔いに注意してください\n` +
4530
- `[S-Drunk] 画面全体を上下左右ランダムに揺らし、さらにレイヤーごとに上下左右に揺らします`,
4687
+ `[S-Drunk] 画面全体を上下左右ランダムに揺らし、さらにレイヤーごとに上下左右に揺らします\n` +
4688
+ `[H-Drunk] S-Drunkより大きく上下に揺らし、さらに回転が掛かります`,
4531
4689
  effect: `矢印・フリーズアローにエフェクトをかけます。\n[Dizzy/Spin] 矢印が回転します\n[Wave/Storm] 矢印の軌道が左右に揺れます\n[Blinking] 矢印が点滅します\n[Squids] 矢印が伸び縮みします`,
4532
4690
  camoufrage: `ステップの見た目が配置は同じでランダムに変わります。`,
4533
4691
  swapping: `ステップゾーンの位置をグループ単位で入れ替えます。`,
@@ -4614,14 +4772,17 @@ const g_lang_msgObj = {
4614
4772
 
4615
4773
  playWindow: `This is the setting for overall rotation of the step zone and arrow position, etc.\n[Stairs/Slope] The step zone is in a staircase shape.\n[Distorted] Distorts the screen.\n` +
4616
4774
  `[SideScroll] It becomes a side scroll mode.`,
4775
+ playWindowType: `[Reverse] Applies reverse rotation to the step zone and arrow positions.`,
4617
4776
  stepArea: `Change the position of the step zone.\n[Halfway] Step zones are centered.\n[2Step] Step zones are divided into two layers.\n` +
4618
4777
  `[Mismatched/R-Mismatched] Scroll direction flows in different directions up and down.\n` +
4619
4778
  `[X-Flower] Lanes spread out like flower petals.\n[Alt-Crossing] Lanes flow from different directions alternately.`,
4620
4779
  frzReturn: `When the Freeze Arrow is reached, and every time the arrow's recovery judgment \nreaches a multiple of 100, it will rotate on either the X, Y, or Z axis.`,
4780
+ frzReturnType: `[360deg/120deg/60deg] Rotates to the specified angle.\n[±360deg/±120deg] May rotate in the opposite direction in addition to 360deg/120deg.\n[Pendulum] Moves back and forth like a pendulum.`,
4621
4781
  shaking: `This sets shaking for the step zone and arrows.\n[Horizontal] Shakes horizontally.\n[Vertical] Shakes vertically.\n` +
4622
4782
  `[X-Horizontal] Per-layer shaking with alternating left/right direction by layer.\n[X-Vertical] Per-layer shaking with alternating up/down direction by layer.\n` +
4623
4783
  `[Drunk] Shakes the entire screen randomly in all directions (may cause motion sickness).\n` +
4624
- `[S-Drunk] Shakes the entire screen randomly in all directions, and also shakes each layer randomly in all directions.`,
4784
+ `[S-Drunk] Shakes the entire screen randomly in all directions, and also shakes each layer randomly in all directions.\n` +
4785
+ `[H-Drunk] Adds stronger vertical movement than S-Drunk and adds rotation.`,
4625
4786
  effect: `Applies effects to the arrows and freeze arrows.\n[Dizzy/Spin] Arrows rotate.\n[Wave/Storm] Swing from left to right.\n[Blinking] Arrows blink.\n[Squids] Arrows stretch and shrink.`,
4626
4787
  camoufrage: `The appearance of the steps changes randomly with the same placement.`,
4627
4788
  swapping: `Replaces the position of step zones on a group-by-group basis.`,
@@ -4684,6 +4845,7 @@ const g_customJsObj = {
4684
4845
  difficulty: [],
4685
4846
  settingsDisplay: [],
4686
4847
  exSetting: [],
4848
+ settingSummary: [],
4687
4849
  keyconfig: [],
4688
4850
 
4689
4851
  preloading: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "45.3.1",
3
+ "version": "45.5.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "./js/danoni_main.js",
6
6
  "scripts": {