danoniplus 47.6.4 → 48.1.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/05/15
7
+ * Revised : 2026/05/20
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 47.6.4`;
12
- const g_revisedDate = `2026/05/15`;
11
+ const g_version = `Ver 48.1.0`;
12
+ const g_revisedDate = `2026/05/20`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -1809,6 +1809,7 @@ const g_handler = (() => {
1809
1809
  if (key in events) {
1810
1810
  const e = events[key];
1811
1811
  e.target.removeEventListener(e.type, e.listener, e.capture);
1812
+ delete events[key];
1812
1813
  }
1813
1814
  }
1814
1815
  };
@@ -2008,6 +2009,7 @@ const makeBgCanvas = (_ctx, { w = g_sWidth, h = g_sHeight } = {}) => {
2008
2009
  * @param {string} [_customDisplayName=''] 画面名(メイン画面: 'Main', それ以外: 空)
2009
2010
  */
2010
2011
  const clearWindow = (_redrawFlg = false, _customDisplayName = ``) => {
2012
+ closeDisplayPreview();
2011
2013
  resetKeyControl();
2012
2014
  resetTransform();
2013
2015
  resetXY();
@@ -6924,7 +6926,7 @@ const commonSettingBtn = _labelName => {
6924
6926
  // キーコンフィグ画面へ移動
6925
6927
  createCss2Button(`btnKeyConfig`, g_lblNameObj.b_keyConfig, () => true, {
6926
6928
  ...g_lblPosObj.btnKeyConfig,
6927
- animationName: (g_initialFlg ? `` : `smallToNormalY`), resetFunc: () => keyConfigInit(`Main`),
6929
+ animationName: (g_initialFlg ? `` : `smallToNormalY`), resetFunc: () => keyConfigInit(`Main`, true),
6928
6930
  }, g_cssObj.button_Setting),
6929
6931
 
6930
6932
  // プレイ開始
@@ -7006,7 +7008,7 @@ const updateSettingSummary = () => {
7006
7008
  const estimatedHighscoreCondition = g_stateObj.dataSaveFlg && (g_stateObj.autoPlay !== C_FLG_ALL && g_headerObj.playbackRate === 1 && g_stateObj.fadein < 10 &&
7007
7009
  (g_stateObj.shuffle === C_FLG_OFF || (g_stateObj.shuffle.endsWith(`Mirror`) && orgShuffleFlg)));
7008
7010
 
7009
- document.getElementById(`lblSummaryDifInfo`).innerHTML = settingData.difData + `${estimatedHighscoreCondition ? '' : ` | <span class="common_kita common_bold">No Records</span>`}`;
7011
+ document.getElementById(`lblSummaryDifInfo`).innerHTML = settingData.difData + `${estimatedHighscoreCondition ? '' : ` | <span class="common_auto common_bold">No Records</span>`}`;
7010
7012
  document.getElementById(`lblSummaryPlaystyleInfo`).textContent = settingData.playStyleData + `${g_stateObj.excessive === C_FLG_ON ? ' | Excessive' : ''}`;
7011
7013
  document.getElementById(`lblSummaryDisplayInfo`).textContent = settingData.displayData;
7012
7014
  document.getElementById(`lblSummaryDisplay2Info`).textContent = settingData.display2Data;
@@ -7086,8 +7088,8 @@ const setSpriteList = _settingList => {
7086
7088
  const spriteList = [];
7087
7089
  Object.keys(_settingList).forEach(setting =>
7088
7090
  spriteList[setting] = createEmptySprite(optionsprite, `${setting}Sprite`, {
7089
- x: 25, y: _settingList[setting].heightPos * g_limitObj.setLblHeight + _settingList[setting].y + 20,
7090
- w: optionWidth + _settingList[setting].dw, h: g_limitObj.setLblHeight + _settingList[setting].dh,
7091
+ x: 25, y: _settingList[setting].heightPos * g_limitObj.setLblHeight + (_settingList[setting].y || 0) + 20,
7092
+ w: optionWidth + (_settingList[setting].dw || 0), h: g_limitObj.setLblHeight + (_settingList[setting].dh || 0),
7091
7093
  }));
7092
7094
  return spriteList;
7093
7095
  };
@@ -7784,9 +7786,9 @@ const makeHighScore = _scoreId => {
7784
7786
  `${g_localStorage.highscores?.[scoreName]?.allPerfect ?? '' ? '<span class="result_AllPerfect">◆</span>' : ''}`, { xPos: 1, dx: 20, yPos: 12, w: 100, align: C_ALIGN_CENTER }),
7785
7787
  createScoreLabel(`lblHClearLamps`, `Cleared: ` + (g_localStorage.highscores?.[scoreName]?.clearLamps?.join(', ') ?? C_FLG_HYPHEN), { yPos: 13, overflow: C_DIS_AUTO, w: g_sWidth / 2 + 40, h: 37 }),
7786
7788
 
7787
- createScoreLabel(`lblHShuffle`, g_stateObj.shuffle.indexOf(`Mirror`) < 0 ? `` : `Shuffle: <span class="common_iknai">${g_stateObj.shuffle}</span>`, { yPos: 11.5, dx: -130 }),
7788
- createScoreLabel(`lblHAssist`, g_autoPlaysBase.includes(g_stateObj.autoPlay) ? `` : `Assist: <span class="common_kita">${g_stateObj.autoPlay}</span>`, { yPos: 12.5, dx: -130 }),
7789
- createScoreLabel(`lblHAnother`, !hasVal(g_keyObj[`transKey${keyCtrlPtn}`]) ? `` : `A.Keymode: <span class="common_ii">${g_keyObj[`transKey${keyCtrlPtn}`]}</span>`, { yPos: 13.5, dx: -130 }),
7789
+ createScoreLabel(`lblHShuffle`, g_stateObj.shuffle.indexOf(`Mirror`) < 0 ? `` : `Shuffle: <span class="common_shuffle">${g_stateObj.shuffle}</span>`, { yPos: 11.5, dx: -130 }),
7790
+ createScoreLabel(`lblHAssist`, g_autoPlaysBase.includes(g_stateObj.autoPlay) ? `` : `Assist: <span class="common_assist">${g_stateObj.autoPlay}</span>`, { yPos: 12.5, dx: -130 }),
7791
+ createScoreLabel(`lblHAnother`, !hasVal(g_keyObj[`transKey${keyCtrlPtn}`]) ? `` : `A.Keymode: <span class="common_another">${g_keyObj[`transKey${keyCtrlPtn}`]}</span>`, { yPos: 13.5, dx: -130 }),
7790
7792
  );
7791
7793
 
7792
7794
  // 結果をクリップボードへコピー (ハイスコア保存分)
@@ -9075,7 +9077,13 @@ const settingsDisplayInit = () => {
9075
9077
  createSettingsDisplayWindow(divRoot);
9076
9078
 
9077
9079
  // ショートカットキーメッセージ
9078
- divRoot.appendChild(createDescDiv(`scMsg`, g_lblNameObj.sdShortcutDesc));
9080
+ multiAppend(divRoot,
9081
+ createDescDiv(`scMsg`, g_lblNameObj.sdShortcutDesc),
9082
+ createCss2Button(`btnDisplayPreview`, `↓ Preview`, _evt => {
9083
+ toggleDisplayPreview();
9084
+ }, g_lblPosObj.btnDisplayPreview, g_cssObj.button_Setting),
9085
+ );
9086
+ createScText(btnDisplayPreview, `DisplayPreview`, { displayName: `settingsDisplay`, targetLabel: `btnDisplayPreview`, x: -25 });
9079
9087
 
9080
9088
  // ユーザカスタムイベント(初期)
9081
9089
  safeExecuteCustomHooks(`g_customJsObj.settingsDisplay`, g_customJsObj.settingsDisplay);
@@ -9090,6 +9098,426 @@ const settingsDisplayInit = () => {
9090
9098
  safeExecuteCustomHooks(`g_skinJsObj.settingsDisplay`, g_skinJsObj.settingsDisplay);
9091
9099
  };
9092
9100
 
9101
+ /** プレビューウィンドウのルートdiv */
9102
+ let g_previewRoot = null;
9103
+
9104
+ /** プレビューで登録した一時リスナー群 */
9105
+ let g_previewLsnrKeys = new Set();
9106
+
9107
+ /** プレビュー内の各UIオブジェクトの現在座標 */
9108
+ const g_previewPos = {
9109
+ jdgJ: { x: null, y: null }, // 通常判定キャラクタ・コンボ
9110
+ jdgFJ: { x: null, y: null }, // フリーズ判定キャラクタ・コンボ
9111
+ };
9112
+
9113
+ /**
9114
+ * プレビュー用リスナー登録(キーをレジストリへ格納)
9115
+ */
9116
+ const addPreviewListener = (target, type, listener, capture = false) => {
9117
+ const key = g_handler.addListener(target, type, listener, capture);
9118
+ g_previewLsnrKeys.add(key);
9119
+ return key;
9120
+ };
9121
+
9122
+ /**
9123
+ * プレビューのトグル(表示 / 非表示)
9124
+ */
9125
+ const toggleDisplayPreview = () => {
9126
+ if (g_previewRoot && document.getElementById(`displayPreviewOverlay`)) {
9127
+ closeDisplayPreview();
9128
+ g_currentPage = `settingsDisplay`;
9129
+ } else {
9130
+ openDisplayPreview();
9131
+ g_currentPage = `displayPreview`;
9132
+ }
9133
+ setShortcutEvent(g_currentPage, () => true, { displayFlg: false });
9134
+ };
9135
+
9136
+ /**
9137
+ * プレビューオーバーレイを開く
9138
+ */
9139
+ const openDisplayPreview = () => {
9140
+ const divRoot = document.getElementById(`divRoot`);
9141
+ if (!divRoot) return;
9142
+
9143
+ // 既存があれば削除
9144
+ closeDisplayPreview();
9145
+
9146
+ // ============================================================
9147
+ // オーバーレイ本体
9148
+ // ============================================================
9149
+ const overlay = createEmptySprite(divRoot, `displayPreviewOverlay`, {
9150
+ w: g_sWidth, h: g_sHeight, background: g_headerObj.baseBrightFlg ? `#eeeeeedd` : `#111111dd`, pointerEvents: C_DIS_AUTO,
9151
+ });
9152
+ g_previewRoot = overlay;
9153
+ multiAppend(overlay,
9154
+ createDivCss2Label(`lblDisplayPreview`, `Display Preview`,
9155
+ g_lblPosObj.lblDisplayPreview, g_cssObj.settings_Display),
9156
+ createCss2Button(`btnDisplayPreview2`, `↑ Preview`, _evt => {
9157
+ toggleDisplayPreview();
9158
+ }, g_lblPosObj.btnDisplayPreview, g_cssObj.button_Setting),
9159
+ createDescDiv(`lblDisplayPreviewMsg`, g_lblNameObj.displayPreviewDesc),
9160
+ );
9161
+
9162
+ // ============================================================
9163
+ // プレイ画面フレーム(白枠)
9164
+ // ============================================================
9165
+ const rate = 0.8;
9166
+ const playW = g_headerObj.playingWidth || g_sWidth;
9167
+ const playH = g_headerObj.playingHeight || g_sHeight;
9168
+ const frameX = Math.round((g_sWidth - playW) / 2);
9169
+ const frameY = Math.round((g_sHeight - playH) / 2);
9170
+
9171
+ const frame = createEmptySprite(overlay, `previewFrame`, {
9172
+ x: frameX, y: frameY, w: playW, h: playH,
9173
+ background: `#111111`,
9174
+ border: `1px solid #444444`,
9175
+ overflow: `hidden`,
9176
+ boxSizing: `border-box`,
9177
+ transform: `scale(${rate})`,
9178
+ });
9179
+
9180
+ // ============================================================
9181
+ // Display設定に応じたUIを描画
9182
+ // ============================================================
9183
+ buildPreviewUI(frame, playW, playH);
9184
+ };
9185
+
9186
+ /**
9187
+ * プレビューオーバーレイを閉じる
9188
+ */
9189
+ const closeDisplayPreview = () => {
9190
+ const overlay = document.getElementById(`displayPreviewOverlay`);
9191
+ if (overlay) {
9192
+ deleteChildspriteAll(`displayPreviewOverlay`);
9193
+ overlay.remove();
9194
+ }
9195
+ // プレビュー専用に登録した残りのハンドラを明示解除
9196
+ if (g_previewLsnrKeys?.size) {
9197
+ g_previewLsnrKeys.forEach(k => g_handler.removeListener(k));
9198
+ g_previewLsnrKeys.clear();
9199
+ }
9200
+ g_previewRoot = null;
9201
+ };
9202
+
9203
+ /**
9204
+ * プレビュー内のUI要素を構築する
9205
+ * @param {HTMLElement} _frame プレイ画面フレーム要素
9206
+ * @param {number} _playW プレイ幅(px)
9207
+ * @param {number} _playH プレイ高さ(px)
9208
+ */
9209
+ const buildPreviewUI = (_frame, _playW, _playH) => {
9210
+
9211
+ // --- Display設定の現在値を取得 ---
9212
+ const d = {
9213
+ stepzone: g_stateObj.d_stepzone,
9214
+ judgment: g_stateObj.d_judgment,
9215
+ lifegauge: g_stateObj.d_lifegauge,
9216
+ score: g_stateObj.d_score,
9217
+ musicinfo: g_stateObj.d_musicinfo,
9218
+ };
9219
+
9220
+ const disableBox = (_name, { x, y, w, h } = {}) =>
9221
+ createDivCss2Label(`previewDisableBox_${_name}`, `${g_emojiObj.crossMark} ${_name}`, {
9222
+ x, y, w, h, background: `rgba(0,0,0,0.5)`, border: `1px dashed #555555`,
9223
+ size: 32, color: `#cccccc`, align: C_ALIGN_LEFT,
9224
+ });
9225
+
9226
+ // ============================================================
9227
+ // ステップゾーン(中央横帯)
9228
+ // ============================================================
9229
+ const stepY = g_posObj.stepY ?? C_STEP_Y;
9230
+ const revStepY = g_posObj.reverseStepY;
9231
+
9232
+ if (d.stepzone === C_FLG_OFF) {
9233
+ multiAppend(_frame,
9234
+ disableBox(`StepZone`, { x: Math.round(_playW / 2 - 200), y: stepY, w: 400, h: 50 }),
9235
+ disableBox(`StepZone_Rev`, { x: Math.round(_playW / 2 - 200), y: C_STEP_Y + revStepY, w: 400, h: 50 }),
9236
+ );
9237
+ } else {
9238
+ // 簡易ステップゾーン(7レーン分)
9239
+ const laneCount = 7;
9240
+ const laneW = 50;
9241
+ const totalW = laneCount * laneW;
9242
+ const startX = Math.round((_playW - totalW) / 2);
9243
+
9244
+ for (let j = 0; j < laneCount; j++) {
9245
+ createEmptySprite(_frame, `previewStep${j}`, {
9246
+ x: startX + j * laneW + 2, y: stepY + 2, w: laneW - 4, h: laneW - 4,
9247
+ background: `rgba(100,100,200,0.25)`,
9248
+ border: `1px solid rgba(150,150,255,0.5)`,
9249
+ });
9250
+ createEmptySprite(_frame, `previewStepR${j}`, {
9251
+ x: startX + j * laneW + 2, y: C_STEP_Y + revStepY + 2, w: laneW - 4, h: laneW - 4,
9252
+ background: `rgba(200,100,100,0.20)`,
9253
+ border: `1px solid rgba(255,150,150,0.4)`,
9254
+ });
9255
+ }
9256
+ }
9257
+
9258
+ // ============================================================
9259
+ // 判定エリア(ドラッグ可能)
9260
+ // ============================================================
9261
+ if (d.judgment === C_FLG_OFF) {
9262
+ _frame.appendChild(disableBox(`Judgment`, {
9263
+ x: Math.round(_playW / 2 - 220), y: Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2 - 60), w: 440, h: 120,
9264
+ }));
9265
+ } else {
9266
+ const jX0 = Math.round(_playW / 2 - 220) + (g_diffObj.arrowJdgX ?? 0);
9267
+ const jY0 = Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2 - 60) + (g_diffObj.arrowJdgY ?? 0);
9268
+ const fX0 = Math.round(_playW / 2 - 120) + (g_diffObj.frzJdgX ?? 0);
9269
+ const fY0 = Math.round((_playH + (g_posObj?.stepYR ?? 0)) / 2 + 10) + (g_diffObj.frzJdgY ?? 0);
9270
+
9271
+ const jdgInitX = g_previewPos.jdgJ.x ?? jX0;
9272
+ const jdgInitY = g_previewPos.jdgJ.y ?? jY0;
9273
+ const jdgFInitX = g_previewPos.jdgFJ.x ?? fX0;
9274
+ const jdgFInitY = g_previewPos.jdgFJ.y ?? fY0;
9275
+
9276
+ // 通常判定グループ
9277
+ buildDraggableJudgGroup(_frame, `jdgJ`, jdgInitX, jdgInitY, _playW, _playH, {
9278
+ charaText: d.judgment === C_FLG_ON ? g_lblNameObj.j_ii : ``,
9279
+ comboText: d.judgment === C_FLG_ON ? `5 Combo!!` : ``,
9280
+ diffText: `Fast 3 Frames`,
9281
+ charaColor: `#66ffff`,
9282
+ });
9283
+
9284
+ // フリーズ判定グループ
9285
+ buildDraggableJudgGroup(_frame, `jdgFJ`, jdgFInitX, jdgFInitY, _playW, _playH, {
9286
+ charaText: d.judgment === C_FLG_ON ? g_lblNameObj.j_kita : ``,
9287
+ comboText: d.judgment === C_FLG_ON ? `5 Combo!!` : ``,
9288
+ diffText: `Fast 2 Frames`,
9289
+ charaColor: `#ffff99`,
9290
+ });
9291
+ }
9292
+
9293
+ // ============================================================
9294
+ // ライフゲージ(左縦帯)
9295
+ // ============================================================
9296
+ if (d.lifegauge === C_FLG_OFF) {
9297
+ _frame.appendChild(disableBox(`LifeGauge`, { x: 5, y: 50, w: 15, h: _playH - 100 }));
9298
+ } else {
9299
+ multiAppend(_frame,
9300
+ createDivCss2Label(`previewLifeBack`, ``, {
9301
+ x: 5, y: 50, w: 15, h: _playH - 100,
9302
+ background: `#333333`, border: `1px solid #555555`,
9303
+ }),
9304
+ createDivCss2Label(`previewLifeBar`, ``, {
9305
+ x: 5, y: 50 + (_playH - 100) * 0.3,
9306
+ w: 15, h: (_playH - 100) * 0.7, background: `#006666`,
9307
+ }),
9308
+ createDivCss2Label(`previewLifeNum`, `700`, {
9309
+ x: 0, y: 30, w: 70, h: 20,
9310
+ size: 14, color: `#ffffff`, background: `#006666`, align: `center`,
9311
+ }),
9312
+ );
9313
+ }
9314
+
9315
+ // ============================================================
9316
+ // スコア・判定カウンタ(右端縦列)
9317
+ // ============================================================
9318
+ if (d.score === C_FLG_OFF) {
9319
+ _frame.appendChild(disableBox(`Score`, { x: _playW - 80, y: 20, w: 70, h: 200 }));
9320
+ } else {
9321
+ const scoreItems = [
9322
+ { color: `#66ffff`, cnt: `5` },
9323
+ { color: `#99ff99`, cnt: `0` },
9324
+ { color: `#ffcc66`, cnt: `0` },
9325
+ { color: `#cc99ff`, cnt: `0` },
9326
+ { color: `#ff9999`, cnt: `0` },
9327
+ { color: `#ffffff`, cnt: `5` },
9328
+ {},
9329
+ { color: `#ffff99`, cnt: `5` },
9330
+ { color: `#99ff66`, cnt: `0` },
9331
+ { color: `#ffffff`, cnt: `5` },
9332
+ ];
9333
+ const sx = _playW - 110;
9334
+ scoreItems.forEach((item, i) => {
9335
+ _frame.appendChild(
9336
+ createDivCss2Label(`previewScore${i}`, item.cnt || ``, {
9337
+ x: sx + 50, y: 20 * (i + 1), w: 50, h: 20,
9338
+ siz: 16, color: item.color, align: `right`,
9339
+ }),
9340
+ );
9341
+ });
9342
+ }
9343
+
9344
+ // ============================================================
9345
+ // 曲名・制作者(左下)
9346
+ // ============================================================
9347
+ if (d.musicinfo === C_FLG_OFF) {
9348
+ _frame.appendChild(disableBox(`MusicInfo`, { x: 5, y: _playH - 50, w: _playW - 125, h: 40 }));
9349
+ } else {
9350
+ multiAppend(
9351
+ _frame,
9352
+ createDivCss2Label(`previewCredit`, `Sample Music / Artist Name`, {
9353
+ ...g_lblPosObj.previewCredit, x: 100, y: _playH - 30, w: _playW - 125, h: 20,
9354
+ }),
9355
+ createDivCss2Label(`previewDifName`, `[7key / Normal]`, {
9356
+ ...g_lblPosObj.previewCredit, x: 100, y: _playH - 16, w: _playW - 125, h: 16, siz: 12,
9357
+ }),
9358
+ createDivCss2Label(`previewTime1`, `0:04 /`, {
9359
+ ...g_lblPosObj.previewCredit, x: 18, y: _playH - 30, w: 40, h: 20, align: C_ALIGN_RIGHT,
9360
+ }),
9361
+ createDivCss2Label(`previewTime2`, `2:54`, {
9362
+ ...g_lblPosObj.previewCredit, x: 60, y: _playH - 30, w: 60, h: 20,
9363
+ }),
9364
+ )
9365
+ }
9366
+ };
9367
+
9368
+ /**
9369
+ * ドラッグ可能な判定グループを生成する
9370
+ * @param {HTMLElement} _parent 親要素
9371
+ * @param {string} _groupId `jdgJ` または `jdgFJ`
9372
+ * @param {number} _initX 初期X座標(frame相対)
9373
+ * @param {number} _initY 初期Y座標(frame相対)
9374
+ * @param {number} _playW プレイ幅
9375
+ * @param {number} _playH プレイ高さ
9376
+ * @param {object} _opts 表示テキスト・色オプション
9377
+ */
9378
+ const buildDraggableJudgGroup = (_parent, _groupId, _initX, _initY, _playW, _playH, _opts) => {
9379
+
9380
+ const group = createEmptySprite(_parent, `previewGrp_${_groupId}`, {
9381
+ x: _initX, y: _initY, w: 370, h: 51, cursor: `grab`, pointerEvents: C_DIS_AUTO,
9382
+ });
9383
+
9384
+ multiAppend(
9385
+ group,
9386
+ // キャラクタ
9387
+ createDivCss2Label(`previewChara_${_groupId}`, _opts.charaText, {
9388
+ x: 0, y: 0, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9389
+ siz: g_limitObj.jdgCharaSiz, color: _opts.charaColor,
9390
+ }),
9391
+ // コンボ
9392
+ createDivCss2Label(`previewCombo_${_groupId}`, _opts.comboText, {
9393
+ x: 170, y: 0, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9394
+ siz: g_limitObj.jdgCharaSiz, color: `#ffffff`,
9395
+ }),
9396
+ // Fast/Slow
9397
+ createDivCss2Label(`previewDiff_${_groupId}`, _opts.diffText, {
9398
+ x: 170, y: 25, w: g_limitObj.jdgCharaWidth, h: g_limitObj.jdgCharaHeight,
9399
+ siz: g_limitObj.mainSiz, color: `#ff9966`,
9400
+ }),
9401
+ );
9402
+
9403
+ // ドラッグハンドル(薄い枠)
9404
+ createEmptySprite(group, `lblHandle_${_groupId}`, {
9405
+ x: 0, y: 0, w: 370, h: 51, border: `1px dashed rgba(255,255,255,0.3)`,
9406
+ boxSizing: `border-box`, borderRadius: `2px`,
9407
+ background: `rgba(255,255,255,0.04)`,
9408
+ });
9409
+
9410
+ // ---- ドラッグ処理 ----
9411
+ let dragging = false;
9412
+ let dragStartX = 0, dragStartY = 0;
9413
+ let elemStartX = 0, elemStartY = 0;
9414
+
9415
+ const keyDown = addPreviewListener(group, `pointerdown`, _evt => {
9416
+ dragging = true;
9417
+ dragStartX = _evt.clientX;
9418
+ dragStartY = _evt.clientY;
9419
+ elemStartX = parseInt(group.style.left, 10);
9420
+ elemStartY = parseInt(group.style.top, 10);
9421
+ group.style.cursor = `grabbing`;
9422
+ group.setPointerCapture(_evt.pointerId);
9423
+ _evt.stopPropagation();
9424
+ });
9425
+ const keyMove = addPreviewListener(group, `pointermove`, _evt => {
9426
+ if (!dragging) return;
9427
+ const dx = _evt.clientX - dragStartX;
9428
+ const dy = _evt.clientY - dragStartY;
9429
+ const newX = Math.max(0, Math.min(_playW - 370, elemStartX + dx));
9430
+ const newY = Math.max(0, Math.min(_playH - 50, elemStartY + dy));
9431
+ group.style.left = wUnit(newX);
9432
+ group.style.top = wUnit(newY);
9433
+ _evt.stopPropagation();
9434
+ });
9435
+ const keyUp = addPreviewListener(group, `pointerup`, _evt => {
9436
+ if (!dragging) return;
9437
+ dragging = false;
9438
+ group.style.cursor = `grab`;
9439
+
9440
+ const finalX = parseInt(group.style.left, 10);
9441
+ const finalY = parseInt(group.style.top, 10);
9442
+
9443
+ // ---- 座標をグローバル状態とゲーム本体に反映 ----
9444
+ g_previewPos[_groupId].x = finalX;
9445
+ g_previewPos[_groupId].y = finalY;
9446
+ applyJudgPositionToGame(_groupId, finalX, finalY);
9447
+
9448
+ _evt.stopPropagation();
9449
+ });
9450
+ // pointerup が届かないケースを拾う
9451
+ addPreviewListener(group, `pointercancel`, _evt => {
9452
+ dragging = false;
9453
+ group.style.cursor = `grab`;
9454
+ });
9455
+ group.setAttribute(`lsnrkey`, keyMove);
9456
+ group.setAttribute(`lsnrkeyTS`, keyDown);
9457
+ group.setAttribute(`lsnrkeyTE`, keyUp);
9458
+ };
9459
+
9460
+ /**
9461
+ * ドラッグ結果の座標をゲーム本体の判定位置設定に反映する
9462
+ * @param {string} _groupId `jdgJ` または `jdgFJ`
9463
+ * @param {number} _x frame相対X
9464
+ * @param {number} _y frame相対Y
9465
+ */
9466
+ const applyJudgPositionToGame = (_groupId, _x, _y) => {
9467
+ const playH = g_headerObj.playingHeight || g_sHeight;
9468
+ const stepYR = g_posObj?.stepYR ?? 0;
9469
+
9470
+ // mainInit内のjdgX[0/1], jdgY[0/1]はローカル変数なため、
9471
+ // g_diffObj経由でオフセットとして保持し、次回プレイ開始時に反映する。
9472
+ // ここでは g_diffObj.arrowJdgY / frzJdgY をオフセット格納先として利用する。
9473
+ //
9474
+ // 「標準Y」= (playH + stepYR) / 2 - 60 (jdgJ の場合)
9475
+ // = (playH + stepYR) / 2 + 10 (jdgFJ の場合)
9476
+ // オフセット = 実際のY - 標準Y
9477
+
9478
+ if (_groupId === `jdgJ`) {
9479
+ const stdX = g_headerObj.playingWidth / 2 - 220;
9480
+ const stdY = Math.round((playH + stepYR) / 2 - 60);
9481
+ g_diffObj.arrowJdgX = _x - stdX;
9482
+ g_diffObj.arrowJdgY = _y - stdY;
9483
+ showToast(`${g_lblNameObj.arrowJdgUpdate}: dX=${g_diffObj.arrowJdgX}, dY=${g_diffObj.arrowJdgY}`);
9484
+ } else if (_groupId === `jdgFJ`) {
9485
+ const stdX = g_headerObj.playingWidth / 2 - 120;
9486
+ const stdY = Math.round((playH + stepYR) / 2 + 10);
9487
+ g_diffObj.frzJdgX = _x - stdX;
9488
+ g_diffObj.frzJdgY = _y - stdY;
9489
+ showToast(`${g_lblNameObj.frzJdgUpdate}: dX=${g_diffObj.frzJdgX}, dY=${g_diffObj.frzJdgY}`);
9490
+ }
9491
+ };
9492
+
9493
+ /**
9494
+ * 画面上部に一時的なトーストメッセージを表示する
9495
+ * @param {string} _msg
9496
+ */
9497
+ function showToast(_msg) {
9498
+ const existing = document.getElementById(`previewToast`);
9499
+ if (existing) existing.remove();
9500
+
9501
+ const toast = createDivCss2Label(`previewToast`, _msg, {
9502
+ x: g_btnX() + g_btnWidth() / 2, y: 50, w: g_btnWidth() / 2, h: 10,
9503
+ transform: `translateX(-50%)`,
9504
+ background: `rgba(0,40,80,0.92)`,
9505
+ color: `#aaddff`,
9506
+ border: `1px solid #3366aa`,
9507
+ borderRadius: `6px`,
9508
+ padding: `6px 16px`,
9509
+ fontSize: `12px`,
9510
+ fontFamily: `monospace`,
9511
+ whiteSpace: `nowrap`,
9512
+ pointerEvents: `none`,
9513
+ transition: `opacity 0.4s`,
9514
+ opacity: `1`,
9515
+ });
9516
+ divRoot.appendChild(toast);
9517
+ setTimeout(() => { toast.style.opacity = `0`; }, 2200);
9518
+ setTimeout(() => { if (toast.parentNode) toast.remove(); }, 2700);
9519
+ };
9520
+
9093
9521
  /**
9094
9522
  * 設定・オプション画面のラベル・ボタン処理の描画
9095
9523
  * @param {Object} _sprite 基準とするスプライト(ここで指定する座標は、そのスプライトからの相対位置)
@@ -9148,7 +9576,7 @@ const createSettingsDisplayWindow = _sprite => {
9148
9576
  g_settings.displayNum[_name] = list.findIndex(flg => flg === g_stateObj[`d_${_name.toLowerCase()}`]);
9149
9577
  displaySprite.appendChild(
9150
9578
  makeSettingLblCssButton(linkId, dispView(), _heightPos, () => switchDisplay(), {
9151
- x: 30 + 180 * _widthPos, w: 170,
9579
+ x: 30 + 180 * _widthPos, y: 20 * _heightPos, w: 170, h: 18,
9152
9580
  title: g_msgObj[`d_${_name.toLowerCase()}`], borderStyle: `solid`,
9153
9581
  cxtFunc: () => switchDisplay(-1),
9154
9582
  }, `button_${cssBgList[g_settings.displayNum[_name]]}`, `button_${cssBarList[g_settings.displayNum[_name]]}`)
@@ -9159,14 +9587,14 @@ const createSettingsDisplayWindow = _sprite => {
9159
9587
  if (g_settings[`d_${_name}s`] !== undefined) {
9160
9588
  displaySprite.appendChild(
9161
9589
  makeSettingLblCssButton(`${linkId}R`, `>`, _heightPos, () => switchDisplay(1, false), {
9162
- x: 175 + 180 * _widthPos, w: 25, cxtFunc: () => switchDisplay(-1, false),
9590
+ x: 175 + 180 * _widthPos, w: 25, y: 2 + 20 * _heightPos, h: 18, cxtFunc: () => switchDisplay(-1, false),
9163
9591
  }, g_cssObj.button_Mini)
9164
9592
  );
9165
9593
  }
9166
9594
  } else {
9167
9595
  displaySprite.appendChild(
9168
9596
  createDivCss2Label(linkId, g_lblNameObj[`d_${toCapitalize(_name)}`] + `:${g_headerObj[`${_name}Set`]}`, {
9169
- x: 30 + 180 * _widthPos, y: 3 + g_limitObj.setLblHeight * _heightPos,
9597
+ x: 30 + 180 * _widthPos, y: 3 + 20 * _heightPos,
9170
9598
  w: 170, siz: g_limitObj.difSelectorSiz,
9171
9599
  }, g_cssObj[`button_Disabled${flg}`])
9172
9600
  );
@@ -9181,7 +9609,7 @@ const createSettingsDisplayWindow = _sprite => {
9181
9609
  const spriteList = setSpriteList(g_settingPos.settingsDisplay);
9182
9610
 
9183
9611
  _sprite.appendChild(createDivCss2Label(`sdDesc`, g_lblNameObj.sdDesc, g_lblPosObj.sdDesc));
9184
- g_displays.forEach((name, j) => makeDisplayButton(name, j % 7, Math.floor(j / 7)));
9612
+ g_displays.forEach((name, j) => makeDisplayButton(name, j % 6, Math.floor(j / 6)));
9185
9613
 
9186
9614
  // ---------------------------------------------------
9187
9615
  // 矢印の見え方 (Appearance)
@@ -9226,9 +9654,7 @@ const createSettingsDisplayWindow = _sprite => {
9226
9654
  // ---------------------------------------------------
9227
9655
  // 判定表示系の不透明度 (Opacity)
9228
9656
  // 縦位置: 9
9229
- g_headerObj.opacityUse = false;
9230
- [`judgment`, `fastSlow`, `filterLine`].forEach(display =>
9231
- g_headerObj.opacityUse ||= g_headerObj[`${display}Use`] || g_headerObj[`${display}Set`] === C_FLG_ON);
9657
+ g_headerObj.opacityUse = g_headerObj.judgmentUse || g_headerObj.judgmentSet === C_FLG_ON;
9232
9658
 
9233
9659
  createGeneralSetting(spriteList.opacity, `opacity`, { unitName: g_lblNameObj.percent });
9234
9660
 
@@ -9444,8 +9870,9 @@ const createGeneralSettingEx = (_spriteList, _name, { defaultList = [C_FLG_OFF],
9444
9870
  /**
9445
9871
  * キーコンフィグ画面初期化
9446
9872
  * @param {string} _kcType
9873
+ * @param {boolean} _initFlg 初期表示フラグ
9447
9874
  */
9448
- const keyConfigInit = (_kcType = g_kcType) => {
9875
+ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
9449
9876
 
9450
9877
  clearWindow(true);
9451
9878
  const divRoot = document.getElementById(`divRoot`);
@@ -9491,6 +9918,36 @@ const keyConfigInit = (_kcType = g_kcType) => {
9491
9918
  g_keyObj[`keyGroupOrder${keyCtrlPtn}`] ?? tkObj.keyGroupList;
9492
9919
  g_keycons.colorCursorNum = 0;
9493
9920
 
9921
+ // 色変化中の初期色を取得(矢印枠のみ)
9922
+ const arrowColorTmp = g_detailObj.miniMapParams[g_stateObj.scoreId]._scoreObj.ncolorData.Arrow;
9923
+ const arrowColors = Array.from({ length: Math.ceil(arrowColorTmp.length / 5) }, (_, i) =>
9924
+ arrowColorTmp.slice(i * 5, i * 5 + 5)
9925
+ ).filter(val => val[0] === 0);
9926
+ const initColors = [];
9927
+ arrowColors.forEach(val => {
9928
+ const laneToken = val[1];
9929
+ const laneStr = String(laneToken ?? ``);
9930
+ if (laneStr.startsWith('g')) {
9931
+ // g付きの場合は矢印グループから対象の矢印番号を検索
9932
+ const groupVal = setIntVal(laneStr.slice(1));
9933
+ for (let j = 0; j < tkObj.keyNum; j++) {
9934
+ if (g_keyObj[`color${tkObj.keyCtrlPtn}`][j] === groupVal) {
9935
+ initColors[j] = makeColorGradation(val[2]);
9936
+ }
9937
+ }
9938
+ } else {
9939
+ const laneIdx = setIntVal(laneToken, -1);
9940
+ if (laneIdx >= 0 && laneIdx < tkObj.keyNum) {
9941
+ initColors[laneIdx] = makeColorGradation(val[2]);
9942
+ }
9943
+ }
9944
+ });
9945
+ if (_initFlg) {
9946
+ g_baseColorGrs = {};
9947
+ const colorKey = Object.keys(g_keyObj).filter(val => val.startsWith(`color${g_keyObj.currentKey}`));
9948
+ colorKey.forEach(val => g_baseColorGrs[val] = g_keyObj[val]);
9949
+ }
9950
+
9494
9951
  /**
9495
9952
  * keyconSpriteのスクロール位置調整
9496
9953
  * @param {number} _targetX
@@ -9509,6 +9966,20 @@ const keyConfigInit = (_kcType = g_kcType) => {
9509
9966
  */
9510
9967
  const getKeyConfigColor = (_j, _colorPos) => {
9511
9968
  let arrowColor = g_headerObj.setColor[_colorPos];
9969
+
9970
+ // 色変化データの利用条件設定(Default/Type0限定)
9971
+ const storageObj = g_stateObj.extraKeyFlg ? g_localStorage : g_localKeyStorage;
9972
+ const baseGroupNum = g_keycons.colorGroupNum === -1
9973
+ ? (storageObj?.[`keyCtrlPtn${g_keyObj.currentKey}`] ?? storageObj?.keyCtrlPtn ?? 0)
9974
+ : g_keycons.colorGroupNum;
9975
+ const currentColorGr = g_keyObj[`color${keyCtrlPtn}_${g_keycons.colorGroupNum}`];
9976
+ const baseColorGr = g_baseColorGrs?.[`color${keyCtrlPtn}_${baseGroupNum}`];
9977
+ if (hasVal(initColors[_j]) && g_keycons.colorDefTypes.includes(g_colorType)
9978
+ && currentColorGr?.[_j] === baseColorGr?.[_j]) {
9979
+ arrowColor = initColors[_j];
9980
+ }
9981
+
9982
+ // アシスト設定時はアシストの色を優先して適用
9512
9983
  if (typeof g_keyObj[`assistPos${keyCtrlPtn}`] === C_TYP_OBJECT &&
9513
9984
  g_keyObj[`assistPos${keyCtrlPtn}`][g_stateObj.autoPlay] !== undefined &&
9514
9985
  !g_autoPlaysBase.includes(g_stateObj.autoPlay)) {
@@ -9809,6 +10280,12 @@ const keyConfigInit = (_kcType = g_kcType) => {
9809
10280
  hasVal(g_keyObj[`transKey${keyCtrlPtn}`]) ? g_lblNameObj.transKeyDesc : ``,
9810
10281
  g_lblPosObj.kcMsg, g_cssObj.keyconfig_warning
9811
10282
  ),
10283
+ // ColorType警告メッセージ
10284
+ createDivCss2Label(
10285
+ `kcMsg2`,
10286
+ g_keycons.colorDefTypes.includes(g_colorType) ? `` : g_lblNameObj.colorTypeDesc,
10287
+ g_lblPosObj.kcMsg2, g_cssObj.keyconfig_Defaultkey
10288
+ ),
9812
10289
 
9813
10290
  // キーカラータイプ切替ボタン
9814
10291
  makeKCButtonHeader(`lblcolorType`, `ColorType`, { x: 10 + g_btnX() }, g_cssObj.keyconfig_ColorType),
@@ -9988,14 +10465,18 @@ const keyConfigInit = (_kcType = g_kcType) => {
9988
10465
  const setColorType = (_scrollNum = 1, _reloadFlg = true) => {
9989
10466
  const nextNum = getNextNum(_scrollNum, `colorTypes`, g_colorType);
9990
10467
  g_colorType = g_keycons.colorTypes[nextNum];
10468
+ const isDefault = g_keycons.colorDefTypes.includes(g_colorType);
9991
10469
  if (g_headerObj.colorUse) {
9992
10470
  g_stateObj.d_color = boolToSwitch(g_keycons.colorDefTypes.findIndex(val => val === g_colorType) !== -1);
9993
10471
  }
9994
10472
  changeSetColor();
9995
10473
  viewGroupObj.color(`_${g_keycons.colorGroupNum}`);
9996
10474
  lnkColorType.textContent = `${getStgDetailName(g_colorType)}${g_localStorage.colorType === g_colorType ? ' *' : ''}`;
10475
+ kcMsg2.textContent = (isDefault || !g_headerObj.colorUse) ? `` : g_lblNameObj.colorTypeDesc;
10476
+ kcMsg2.style.top = wUnit(hasVal(g_keyObj[`transKey${keyCtrlPtn}`]) ? g_lblPosObj.kcMsg2.y : g_lblPosObj.kcMsg.y);
10477
+ kcMsg2.style.fontSize = wUnit(getFontSize2(kcMsg2.textContent, g_btnWidth()));
9997
10478
  if (_reloadFlg) {
9998
- colorPickSprite.style.display = ([`Default`, `Type0`].includes(g_colorType) ? C_DIS_NONE : C_DIS_INHERIT);
10479
+ colorPickSprite.style.display = isDefault ? C_DIS_NONE : C_DIS_INHERIT;
9999
10480
  g_keycons.colorCursorNum = g_keycons.colorCursorNum % Math.ceil(g_headerObj.setColor.length / g_limitObj.kcColorPickerNum);
10000
10481
  changeColorPickers();
10001
10482
  }
@@ -10017,7 +10498,7 @@ const keyConfigInit = (_kcType = g_kcType) => {
10017
10498
  };
10018
10499
 
10019
10500
  const colorPickSprite = createEmptySprite(divRoot, `colorPickSprite`, { ...g_windowObj.colorPickSprite, title: g_msgObj.pickArrow });
10020
- if ([`Default`, `Type0`].includes(g_colorType)) {
10501
+ if (g_keycons.colorDefTypes.includes(g_colorType)) {
10021
10502
  colorPickSprite.style.display = C_DIS_NONE;
10022
10503
  }
10023
10504
  multiAppend(colorPickSprite,
@@ -10376,7 +10857,6 @@ const keyconfigKeyboardPreview = (() => {
10376
10857
  // 定数
10377
10858
  // -------------------------------------------------------------------------
10378
10859
  const C_PREVIEW_ID = `kbPreviewArea`;
10379
- const C_BTN_ID = `btnKbPreview`;
10380
10860
  const C_CANVAS_BASE_ID = `kbCanvasBase`;
10381
10861
  const C_CANVAS_MAP_ID = `kbCanvasMap`;
10382
10862
 
@@ -10885,18 +11365,11 @@ const keyconfigKeyboardPreview = (() => {
10885
11365
  const init = divRoot => {
10886
11366
  calcScale();
10887
11367
 
10888
- // ボタン: キャンバス横幅中央に配置、小さいサイズ
10889
- const btnW = 80;
10890
- const btnX = g_btnX() + Math.floor((g_btnWidth() - btnW) / 2);
10891
-
10892
11368
  // "↓ Preview" → 展開、"↑ Preview" → 閉じる のトグルボタン
10893
- const btn = createCss2Button(C_BTN_ID, `↓ Preview`, () => {
11369
+ const btn = createCss2Button(`btnKbPreview`, `↓ Preview`, () => {
10894
11370
  togglePreview();
10895
11371
  btn.textContent = _state.visible ? `↑ Preview` : `↓ Preview`;
10896
- }, {
10897
- x: btnX, y: BTN_Y, w: btnW, h: BTN_H, siz: BTN_FS,
10898
- title: g_msgObj.kcPreview,
10899
- }, g_cssObj.button_Setting);
11372
+ }, g_lblPosObj.btnKbPreview, g_cssObj.button_Setting);
10900
11373
  divRoot.appendChild(btn);
10901
11374
 
10902
11375
  // プレビューエリア: 水平・垂直センタリング
@@ -11052,7 +11525,7 @@ const updateKeyInfo = (_header, _keyCtrlPtn) => {
11052
11525
  * - ここでのID管理は1譜面目も区別して設定する (setScoreIdHeaderの第三引数を使用)
11053
11526
  */
11054
11527
  const changeSetColor = () => {
11055
- const isDefault = [`Default`, `Type0`].includes(g_colorType);
11528
+ const isDefault = g_keycons.colorDefTypes.includes(g_colorType);
11056
11529
  const idHeader = setScoreIdHeader(g_stateObj.scoreId, false, true);
11057
11530
  const defaultType = idHeader + g_colorType;
11058
11531
  const currentTypes = {
@@ -12144,7 +12617,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
12144
12617
  // 歌詞データの分解 (3つで1セット, セット毎の改行区切り可)
12145
12618
  obj.wordData = [];
12146
12619
  obj.wordMaxDepth = -1;
12147
- if (g_stateObj.d_lyrics === C_FLG_OFF) {
12620
+ if (g_stateObj.d_background === C_FLG_OFF) {
12148
12621
  } else {
12149
12622
  [obj.wordData, obj.wordMaxDepth] = makeWordData(scoreIdHeader);
12150
12623
  }
@@ -13344,6 +13817,8 @@ const getArrowSettings = () => {
13344
13817
  const lowerDisp = _disp.toLowerCase();
13345
13818
  g_workObj[`${lowerDisp}Disp`] = (g_stateObj[`d_${lowerDisp}`] === C_FLG_OFF ? C_DIS_NONE : C_DIS_INHERIT);
13346
13819
  });
13820
+ g_workObj.judgmentDisp = g_stateObj.d_judgment !== C_FLG_ON ? C_DIS_NONE : C_DIS_INHERIT;
13821
+ g_workObj.fastslowDisp = g_stateObj.d_judgment === C_FLG_OFF ? C_DIS_NONE : C_DIS_INHERIT;
13347
13822
 
13348
13823
  g_workObj.lifeVal = Math.floor(g_workObj.lifeInit * 100) / 100;
13349
13824
  g_workObj.arrowReturnVal = 0;
@@ -13641,11 +14116,11 @@ const mainInit = () => {
13641
14116
  if (g_appearanceRanges.includes(g_stateObj.appearance)) {
13642
14117
  mainSprite.appendChild(createDivCss2Label(`filterView`, ``, g_lblPosObj.filterView));
13643
14118
  if (g_stateObj.d_filterline === C_FLG_ON) {
13644
- $id(`filterView`).opacity = objOpacity;
14119
+ $id(`filterView`).opacity = 1;
13645
14120
  for (let j = 0; j < g_stateObj.layerNum; j++) {
13646
- $id(`filterBar${j}`).opacity = objOpacity;
14121
+ $id(`filterBar${j}`).opacity = 1;
13647
14122
  if (doubleFilterFlg) {
13648
- $id(`filterBar${j}_HS`).opacity = objOpacity;
14123
+ $id(`filterBar${j}_HS`).opacity = 1;
13649
14124
  }
13650
14125
  }
13651
14126
  }
@@ -13819,7 +14294,7 @@ const mainInit = () => {
13819
14294
  multiAppend(infoSprite,
13820
14295
  // FrzReturnゲージ
13821
14296
  createColorObject2(`lifeBackFrzObj`, { ...g_lblPosObj.lifeBackFrzObj, display: g_workObj.scoreDisp }, g_cssObj.life_Background),
13822
- createColorObject2(`lifeBarFrz`, { ...g_lblPosObj.lifeBarFrz, display: g_workObj.scoreDisp }, g_cssObj.main_stepShobon),
14297
+ createColorObject2(`lifeBarFrz`, { ...g_lblPosObj.lifeBarFrz, display: g_workObj.scoreDisp }, g_cssObj.life_frzNormal),
13823
14298
  )
13824
14299
  }
13825
14300
 
@@ -13850,8 +14325,12 @@ const mainInit = () => {
13850
14325
  const jdgGroups = [`J`, `FJ`];
13851
14326
  const jdgX = [g_headerObj.playingWidth / 2 - 220, g_headerObj.playingWidth / 2 - 120];
13852
14327
  const jdgY = [(g_headerObj.playingHeight + g_posObj.stepYR) / 2 - 60, (g_headerObj.playingHeight + g_posObj.stepYR) / 2 + 10];
13853
- if (g_stateObj.d_background === C_FLG_OFF && g_headerObj.jdgPosReset) {
14328
+ if (g_stateObj.d_background === C_FLG_OFF && g_headerObj.jdgPosReset && g_diffObj.arrowJdgX === 0) {
14329
+ // jdgPosResetオプションにより判定位置変更が阻害されることを防ぐため、
14330
+ // X座標が変わった場合は判定位置変更が行われたと判断
13854
14331
  } else {
14332
+ jdgX[0] += g_diffObj.arrowJdgX;
14333
+ jdgX[1] += g_diffObj.frzJdgX;
13855
14334
  jdgY[0] += g_diffObj.arrowJdgY;
13856
14335
  jdgY[1] += g_diffObj.frzJdgY;
13857
14336
  }
@@ -14176,7 +14655,7 @@ const mainInit = () => {
14176
14655
  // 矢印(枠外判定、AutoPlay: OFF)
14177
14656
  arrowOFF: (_j, _arrowName, _cnt) => {
14178
14657
  if (_cnt < (-1) * g_judgObj.arrowJ[g_judgPosObj.shobon]) {
14179
- judgeUwan(_cnt);
14658
+ judgeUwan(_cnt, _j);
14180
14659
  judgeObjDelete.arrow(_j, _arrowName);
14181
14660
  }
14182
14661
  },
@@ -14186,7 +14665,7 @@ const mainInit = () => {
14186
14665
  if (_cnt === 0) {
14187
14666
  const stepDivHit = document.getElementById(`stepHit${_j}`);
14188
14667
 
14189
- judgeIi(_cnt);
14668
+ judgeIi(_cnt, _j);
14190
14669
  stepDivHit.style.opacity = 1;
14191
14670
  stepDivHit.setAttribute(`cnt`, C_FRM_HITMOTION);
14192
14671
  judgeObjDelete.arrow(_j, _arrowName);
@@ -14198,7 +14677,7 @@ const mainInit = () => {
14198
14677
  if (_cnt === 0) {
14199
14678
  const stepDivHit = document.getElementById(`stepHit${_j}`);
14200
14679
 
14201
- safeExecuteCustomHooks(`g_customJsObj.dummyArrow`, g_customJsObj.dummyArrow);
14680
+ safeExecuteCustomHooks(`g_customJsObj.dummyArrow`, g_customJsObj.dummyArrow, _j);
14202
14681
  stepDivHit.style.top = wUnit(-15);
14203
14682
  stepDivHit.style.opacity = 1;
14204
14683
  stepDivHit.classList.value = ``;
@@ -14214,7 +14693,7 @@ const mainInit = () => {
14214
14693
 
14215
14694
  // フリーズアロー(成功時)
14216
14695
  frzOK: (_j, _k, _frzName, _cnt) => {
14217
- judgeKita(_cnt);
14696
+ judgeKita(_cnt, _j);
14218
14697
  $id(`frzHit${_j}`).opacity = 0;
14219
14698
  g_attrObj[_frzName].judgEndFlg = true;
14220
14699
  judgeObjDelete.frz(_j, _frzName);
@@ -14222,7 +14701,7 @@ const mainInit = () => {
14222
14701
 
14223
14702
  // ダミーフリーズアロー(成功時)
14224
14703
  dummyFrzOK: (_j, _k, _frzName, _cnt) => {
14225
- safeExecuteCustomHooks(`g_customJsObj.dummyFrz`, g_customJsObj.dummyFrz);
14704
+ safeExecuteCustomHooks(`g_customJsObj.dummyFrz`, g_customJsObj.dummyFrz, _j);
14226
14705
  $id(`frzHit${_j}`).opacity = 0;
14227
14706
  g_attrObj[_frzName].judgEndFlg = true;
14228
14707
  judgeObjDelete.dummyFrz(_j, _frzName);
@@ -14231,12 +14710,12 @@ const mainInit = () => {
14231
14710
  // フリーズアロー(枠外判定)
14232
14711
  frzNG: (_j, _k, _frzName, _cnt) => {
14233
14712
  if (_cnt < (-1) * g_judgObj.frzJ[g_judgPosObj.iknai]) {
14234
- judgeIknai(_cnt);
14713
+ judgeIknai(_cnt, _j);
14235
14714
  g_attrObj[_frzName].judgEndFlg = true;
14236
14715
 
14237
14716
  changeFailedFrz(_j, _k);
14238
14717
  if (g_headerObj.frzStartjdgUse) {
14239
- judgeUwan(_cnt);
14718
+ judgeUwan(_cnt, _j);
14240
14719
  }
14241
14720
  }
14242
14721
  },
@@ -14247,7 +14726,7 @@ const mainInit = () => {
14247
14726
  // フリーズアロー(キーを離したときの処理)
14248
14727
  frzKeyUp: (_j, _k, _frzName, _cnt) => {
14249
14728
  if (g_attrObj[_frzName].keyUpFrame > g_headerObj.frzAttempt) {
14250
- judgeIknai(_cnt);
14729
+ judgeIknai(_cnt, _j);
14251
14730
  g_attrObj[_frzName].judgEndFlg = true;
14252
14731
  changeFailedFrz(_j, _k);
14253
14732
  }
@@ -14289,7 +14768,7 @@ const mainInit = () => {
14289
14768
 
14290
14769
  // 自身より前の矢印が未判定の場合、強制的に枠外判定を行い矢印を削除
14291
14770
  if (prevArrow.cnt >= (-1) * g_judgObj.arrowJ[g_judgPosObj.uwan]) {
14292
- judgeUwan(prevArrow.cnt);
14771
+ judgeUwan(prevArrow.cnt, _j);
14293
14772
  judgeObjDelete.arrow(_j, prevArrowName);
14294
14773
  }
14295
14774
  }
@@ -14316,9 +14795,9 @@ const mainInit = () => {
14316
14795
 
14317
14796
  // 自身より前のフリーズアローが未判定の場合、強制的に枠外判定を行う
14318
14797
  if (prevFrz.cnt >= (-1) * g_judgObj.frzJ[g_judgPosObj.iknai] && !prevFrz.judgEndFlg) {
14319
- judgeIknai(prevFrz.cnt);
14798
+ judgeIknai(prevFrz.cnt, _j);
14320
14799
  if (g_headerObj.frzStartjdgUse) {
14321
- judgeUwan(prevFrz.cnt);
14800
+ judgeUwan(prevFrz.cnt, _j);
14322
14801
  }
14323
14802
  }
14324
14803
  // 自身より前のフリーズアローを削除して判定対象を自身に変更 (g_workObj.judgFrzCnt[_j]をカウントアップ)
@@ -14332,7 +14811,7 @@ const mainInit = () => {
14332
14811
  if (_cnt === 0) {
14333
14812
  changeHitFrz(_j, _k, `frz`);
14334
14813
  if (g_headerObj.frzStartjdgUse) {
14335
- judgeIi(_cnt);
14814
+ judgeIi(_cnt, _j);
14336
14815
  }
14337
14816
  }
14338
14817
  },
@@ -15204,8 +15683,8 @@ const startFrzReturn = () => {
15204
15683
  clearTimeout(g_workObj.frzReturnTimerId);
15205
15684
  g_workObj.frzReturnTimerId = null;
15206
15685
  }
15207
- lifeBarFrz.classList.remove(g_cssObj.main_stepShobon, g_cssObj.main_stepMatari);
15208
- lifeBarFrz.classList.add(g_cssObj.main_stepMatari);
15686
+ lifeBarFrz.classList.remove(g_cssObj.life_frzNormal, g_cssObj.life_frzActive);
15687
+ lifeBarFrz.classList.add(g_cssObj.life_frzActive);
15209
15688
  const seqLen = g_workObj.frzReturnSeq.length;
15210
15689
  executeFrzReturn(
15211
15690
  g_workObj.frzReturnSeq[seqLen > 1 ? Math.floor(Math.random() * seqLen) : 0], 0,
@@ -15236,8 +15715,8 @@ const executeFrzReturn = (_seq, _idx, _axis) => {
15236
15715
  g_workObj.frzReturnFlg = false;
15237
15716
  g_workObj.frzReturnTimerId = null;
15238
15717
  const frzReturnGauge = document.getElementById(`lifeBarFrz`);
15239
- frzReturnGauge.classList.remove(g_cssObj.main_stepShobon, g_cssObj.main_stepMatari);
15240
- frzReturnGauge.classList.add(g_cssObj.main_stepShobon);
15718
+ frzReturnGauge.classList.remove(g_cssObj.life_frzNormal, g_cssObj.life_frzActive);
15719
+ frzReturnGauge.classList.add(g_cssObj.life_frzNormal);
15241
15720
  return;
15242
15721
  }
15243
15722
 
@@ -15470,7 +15949,7 @@ const changeHitFrz = (_j, _k, _name, _difFrame = 0) => {
15470
15949
  if (g_stateObj.frzReturn !== C_FLG_OFF) {
15471
15950
  startFrzReturn();
15472
15951
  }
15473
- safeExecuteCustomHooks(`g_customJsObj.judg_${_name}Hit`, g_customJsObj[`judg_${_name}Hit`], _difFrame);
15952
+ safeExecuteCustomHooks(`g_customJsObj.judg_${_name}Hit`, g_customJsObj[`judg_${_name}Hit`], _difFrame, _j);
15474
15953
  };
15475
15954
 
15476
15955
  /**
@@ -15544,7 +16023,7 @@ const judgeArrow = _j => {
15544
16023
  } else if (_difCnt <= g_judgObj.arrowJ[g_judgPosObj.shobon]) {
15545
16024
  // 通常判定
15546
16025
  const [resultFunc, resultJdg] = checkJudgment(_difCnt);
15547
- resultFunc(_difFrame);
16026
+ resultFunc(_difFrame, _j);
15548
16027
  displayDiff(_difFrame);
15549
16028
  stepHitTargetArrow(resultJdg);
15550
16029
  document.getElementById(arrowName).remove();
@@ -15561,7 +16040,7 @@ const judgeArrow = _j => {
15561
16040
 
15562
16041
  if (g_headerObj.frzStartjdgUse) {
15563
16042
  const [resultFunc] = checkJudgment(_difCnt);
15564
- resultFunc(_difFrame);
16043
+ resultFunc(_difFrame, _j);
15565
16044
  displayDiff(_difFrame);
15566
16045
  } else {
15567
16046
  displayDiff(_difFrame, `F`);
@@ -15572,7 +16051,7 @@ const judgeArrow = _j => {
15572
16051
  } else {
15573
16052
  changeFailedFrz(_j, fcurrentNo);
15574
16053
  if (g_headerObj.frzStartjdgUse) {
15575
- judgeIknai(_difFrame);
16054
+ judgeIknai(_difFrame, _j);
15576
16055
  currentFrz.judgEndFlg = true;
15577
16056
  }
15578
16057
  }
@@ -15708,8 +16187,9 @@ const updateCombo = () => {
15708
16187
  * 回復判定の共通処理
15709
16188
  * @param {string} _name
15710
16189
  * @param {number} _difFrame
16190
+ * @param {number} _j
15711
16191
  */
15712
- const judgeRecovery = (_name, _difFrame) => {
16192
+ const judgeRecovery = (_name, _difFrame, _j) => {
15713
16193
  changeJudgeCharacter(_name, g_lblNameObj[`j_${_name}`]);
15714
16194
  updateCombo();
15715
16195
  lifeRecovery();
@@ -15727,65 +16207,72 @@ const judgeRecovery = (_name, _difFrame) => {
15727
16207
  if (_name === `shakin`) {
15728
16208
  quickRetry(`Shakin(Great)`);
15729
16209
  }
15730
- safeExecuteCustomHooks(`g_customJsObj.judg_${_name}`, g_customJsObj[`judg_${_name}`], _difFrame);
16210
+ safeExecuteCustomHooks(`g_customJsObj.judg_${_name}`, g_customJsObj[`judg_${_name}`], _difFrame, _j);
15731
16211
  };
15732
16212
 
15733
16213
  /**
15734
16214
  * ダメージ系共通処理
15735
16215
  * @param {string} _name
15736
16216
  * @param {number} _difFrame
16217
+ * @param {number} _j
15737
16218
  */
15738
- const judgeDamage = (_name, _difFrame) => {
16219
+ const judgeDamage = (_name, _difFrame, _j) => {
15739
16220
  changeJudgeCharacter(_name, g_lblNameObj[`j_${_name}`]);
15740
16221
  g_resultObj.combo = 0;
15741
16222
  comboJ.textContent = ``;
15742
16223
  diffJ.textContent = ``;
15743
16224
  lifeDamage();
15744
- safeExecuteCustomHooks(`g_customJsObj.judg_${_name}`, g_customJsObj[`judg_${_name}`], _difFrame);
16225
+ safeExecuteCustomHooks(`g_customJsObj.judg_${_name}`, g_customJsObj[`judg_${_name}`], _difFrame, _j);
15745
16226
  };
15746
16227
 
15747
16228
  /**
15748
16229
  * 判定処理:イイ
15749
16230
  * @param {number} _difFrame
16231
+ * @param {number} _j
15750
16232
  */
15751
- const judgeIi = _difFrame => judgeRecovery(`ii`, _difFrame);
16233
+ const judgeIi = (_difFrame, _j) => judgeRecovery(`ii`, _difFrame, _j);
15752
16234
 
15753
16235
  /**
15754
16236
  * 判定処理:シャキン
15755
16237
  * @param {number} _difFrame
16238
+ * @param {number} _j
15756
16239
  */
15757
- const judgeShakin = _difFrame => judgeRecovery(`shakin`, _difFrame);
16240
+ const judgeShakin = (_difFrame, _j) => judgeRecovery(`shakin`, _difFrame, _j);
15758
16241
 
15759
16242
  /**
15760
16243
  * 判定処理:マターリ
15761
16244
  * @param {number} _difFrame
16245
+ * @param {number} _j
15762
16246
  */
15763
- const judgeMatari = _difFrame => {
16247
+ const judgeMatari = (_difFrame, _j) => {
15764
16248
  changeJudgeCharacter(`matari`, g_lblNameObj.j_matari);
15765
16249
  comboJ.textContent = ``;
15766
16250
  finishViewing();
15767
16251
  quickRetry(`Matari(Good)`);
15768
16252
 
15769
- safeExecuteCustomHooks(`g_customJsObj.judg_matari`, g_customJsObj.judg_matari, _difFrame);
16253
+ safeExecuteCustomHooks(`g_customJsObj.judg_matari`, g_customJsObj.judg_matari, _difFrame, _j);
15770
16254
  };
15771
16255
 
15772
16256
  /**
15773
16257
  * 判定処理:ショボーン
15774
16258
  * @param {number} _difFrame
16259
+ * @param {number} _j
15775
16260
  */
15776
- const judgeShobon = _difFrame => judgeDamage(`shobon`, _difFrame);
16261
+ const judgeShobon = (_difFrame, _j) => judgeDamage(`shobon`, _difFrame, _j);
15777
16262
 
15778
16263
  /**
15779
16264
  * 判定処理:ウワァン
15780
16265
  * @param {number} _difFrame
16266
+ * @param {number} _j
15781
16267
  */
15782
- const judgeUwan = _difFrame => judgeDamage(`uwan`, _difFrame);
16268
+ const judgeUwan = (_difFrame, _j) => judgeDamage(`uwan`, _difFrame, _j);
15783
16269
 
15784
16270
  /**
15785
16271
  * 判定処理:キター
15786
16272
  * @param {number} _difFrame
16273
+ * @param {number} _j
15787
16274
  */
15788
- const judgeKita = _difFrame => {
16275
+ const judgeKita = (_difFrame, _j) => {
15789
16276
  changeJudgeCharacter(`kita`, g_lblNameObj.j_kita, `F`);
15790
16277
 
15791
16278
  if (++g_resultObj.fCombo > g_resultObj.fmaxCombo) {
@@ -15797,21 +16284,22 @@ const judgeKita = _difFrame => {
15797
16284
  lifeRecovery();
15798
16285
  finishViewing();
15799
16286
 
15800
- safeExecuteCustomHooks(`g_customJsObj.judg_kita`, g_customJsObj.judg_kita, _difFrame);
16287
+ safeExecuteCustomHooks(`g_customJsObj.judg_kita`, g_customJsObj.judg_kita, _difFrame, _j);
15801
16288
  };
15802
16289
 
15803
16290
  /**
15804
16291
  * 判定処理:イクナイ
15805
16292
  * @param {number} _difFrame
16293
+ * @param {number} _j
15806
16294
  */
15807
- const judgeIknai = _difFrame => {
16295
+ const judgeIknai = (_difFrame, _j) => {
15808
16296
  changeJudgeCharacter(`iknai`, g_lblNameObj.j_iknai, `F`);
15809
16297
  comboFJ.textContent = ``;
15810
16298
  g_resultObj.fCombo = 0;
15811
16299
 
15812
16300
  lifeDamage();
15813
16301
 
15814
- safeExecuteCustomHooks(`g_customJsObj.judg_iknai`, g_customJsObj.judg_iknai, _difFrame);
16302
+ safeExecuteCustomHooks(`g_customJsObj.judg_iknai`, g_customJsObj.judg_iknai, _difFrame, _j);
15815
16303
  };
15816
16304
 
15817
16305
  const jdgList = [`ii`, `shakin`, `matari`, `shobon`].map(jdg => toCapitalize(jdg));
@@ -16728,7 +17216,6 @@ const getSelectedSettingList = (_orgShuffleFlg) => {
16728
17216
  let displayData = [
16729
17217
  withDisplays(g_stateObj.d_stepzone, C_FLG_ON, g_lblNameObj.rd_StepZone),
16730
17218
  withDisplays(g_stateObj.d_judgment, C_FLG_ON, g_lblNameObj.rd_Judgment),
16731
- withDisplays(g_stateObj.d_fastslow, C_FLG_ON, g_lblNameObj.rd_FastSlow),
16732
17219
  withDisplays(g_stateObj.d_lifegauge, C_FLG_ON, g_lblNameObj.rd_LifeGauge),
16733
17220
  withDisplays(g_stateObj.d_score, C_FLG_ON, g_lblNameObj.rd_Score),
16734
17221
  withDisplays(g_stateObj.d_musicinfo, C_FLG_ON, g_lblNameObj.rd_MusicInfo),
@@ -16748,7 +17235,6 @@ const getSelectedSettingList = (_orgShuffleFlg) => {
16748
17235
  let display2Data = [
16749
17236
  withDisplays(g_stateObj.d_velocity, C_FLG_ON, g_lblNameObj.rd_Velocity),
16750
17237
  withDisplays(g_stateObj.d_color, C_FLG_ON, g_lblNameObj.rd_Color),
16751
- withDisplays(g_stateObj.d_lyrics, C_FLG_ON, g_lblNameObj.rd_Lyrics),
16752
17238
  withDisplays(g_stateObj.d_background, C_FLG_ON, g_lblNameObj.rd_Background),
16753
17239
  withDisplays(g_stateObj.d_arroweffect, C_FLG_ON, g_lblNameObj.rd_ArrowEffect),
16754
17240
  withDisplays(g_stateObj.d_special, C_FLG_ON, g_lblNameObj.rd_Special),