danoniplus 40.2.0 → 40.3.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 : 2025/03/07
7
+ * Revised : 2025/03/08
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 40.2.0`;
12
- const g_revisedDate = `2025/03/07`;
11
+ const g_version = `Ver 40.3.0`;
12
+ const g_revisedDate = `2025/03/08`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -475,19 +475,20 @@ const getIndent = (_level) => ' '.repeat(_level * 4);
475
475
  * ストレージ情報の取得
476
476
  * @param {string} _name g_storageFuncの実行キー名
477
477
  * @param {string} _key g_storageFuncの実行キーの引数
478
+ * @param {boolean} [_colorFmt=true]
478
479
  * @returns {string}
479
480
  */
480
- const viewKeyStorage = (_name, _key = ``) => {
481
+ const viewKeyStorage = (_name, _key = ``, _colorFmt = true) => {
481
482
 
482
483
  // キャッシュ設定
483
484
  if (!viewKeyStorage.cache) {
484
485
  viewKeyStorage.cache = new Map();
485
486
  }
486
- const cacheKey = _key + _name;
487
+ const cacheKey = _key + _name + String(_colorFmt);
487
488
  if (viewKeyStorage.cache.has(cacheKey)) {
488
489
  return viewKeyStorage.cache.get(cacheKey);
489
490
  }
490
- const result = formatObject(g_storageFunc.get(_name)?.(_key) || setVal(_name, ``, C_TYP_CALC));
491
+ const result = formatObject(g_storageFunc.get(_name)?.(_key) || setVal(_name, ``, C_TYP_CALC), 0, { colorFmt: _colorFmt });
491
492
  viewKeyStorage.cache.set(cacheKey, result);
492
493
  return result;
493
494
  }
@@ -2538,6 +2539,44 @@ const initialControl = async () => {
2538
2539
  delete g_keyObj[key];
2539
2540
  }
2540
2541
  });
2542
+
2543
+ // エディター用のフォーマッター作成
2544
+ const customKeyList = g_headerObj.keyLists.filter(val =>
2545
+ g_keyObj.defaultKeyList.findIndex(key => key === val) < 0);
2546
+
2547
+ customKeyList.forEach(key => {
2548
+ const keyBase = `${key}_0`;
2549
+ const keyCtrlPtn = `${g_keyObj.defaultProp}${keyBase}`;
2550
+ const keyGroup = g_keyObj[`keyGroup${keyBase}`];
2551
+ const keyGroupList = makeDedupliArray(keyGroup.flat());
2552
+ const orgKeyNum = g_keyObj[keyCtrlPtn].length;
2553
+ const baseX = Math.floor(Math.random() * (100 - keyGroupList.length));
2554
+
2555
+ keyGroupList.forEach((keyGroupNo, j) => {
2556
+ const keyN = keyGroupNo === `0` ? key : `${key}_${j + 1}`;
2557
+ const filterCond = (j) => keyGroup[j].findIndex(val => val === keyGroupNo) >= 0;
2558
+ const keyCtrlList = g_keyObj[keyCtrlPtn].filter((val, j) => filterCond(j));
2559
+ const charaList = g_keyObj[`chara${keyBase}`].filter((val, j) => filterCond(j));
2560
+ const colorList = g_keyObj[`color${keyBase}_0`].filter((val, j) => filterCond(j));
2561
+ const keyNum = g_keyObj[keyCtrlPtn].filter((val, j) => filterCond(j)).length;
2562
+
2563
+ g_editorTmp[keyN] = {};
2564
+ g_editorTmp[keyN].id = orgKeyNum * 100 + baseX + j;
2565
+ g_editorTmp[keyN].num = keyNum;
2566
+ g_editorTmp[keyN].chars = keyCtrlList.map(val => g_kCd[val[0]]);
2567
+ g_editorTmp[keyN].keys = keyCtrlList.map(val => g_kCdN[val[0]]).map(val => replaceStr(val, g_escapeStr.editorKey));
2568
+ g_editorTmp[keyN].alternativeKeys = keyCtrlList.map(val => val[1] === 0 ? `` : g_kCdN[val[1]]).map(val => replaceStr(val, g_escapeStr.editorKey));
2569
+ g_editorTmp[keyN].noteNames = charaList.map(val => `${val}_data`);
2570
+ g_editorTmp[keyN].freezeNames = charaList.map(val => {
2571
+ let frzName = replaceStr(val, g_escapeStr.frzName);
2572
+ if (frzName.indexOf(`frz`) === -1 && frzName.indexOf(`foni`) === -1) {
2573
+ frzName = frzName.replaceAll(frzName, `frz${toCapitalize(frzName)}`);
2574
+ }
2575
+ return `${frzName}_data`;
2576
+ });
2577
+ g_editorTmp[keyN].colorGroup = colorList.map(val => val % 3);
2578
+ });
2579
+ });
2541
2580
  };
2542
2581
 
2543
2582
  /**
@@ -5009,10 +5048,12 @@ const dataMgtInit = () => {
5009
5048
  g_stateObj[`dm_${key}`] = C_FLG_OFF;
5010
5049
  g_settings.dataMgtNum[key] = 0;
5011
5050
 
5051
+ const keyWidth = Math.min(Math.max(50, getStrWidth(getKeyName(key), g_limitObj.setLblSiz, getBasicFont())), 80);
5012
5052
  keyListSprite.appendChild(createMgtButton(key, j - 2, 0, {
5013
- w: Math.max(50, getStrWidth(getKeyName(key) + ` `, g_limitObj.setLblSiz, getBasicFont())),
5053
+ w: keyWidth,
5054
+ siz: getFontSize(getKeyName(key), keyWidth, getBasicFont(), g_limitObj.setLblSiz, 10),
5014
5055
  }));
5015
- document.getElementById(`btn${key}`).innerHTML = getKeyName(key);
5056
+ document.getElementById(`btn${toCapitalize(key)}`).innerHTML = getKeyName(key);
5016
5057
 
5017
5058
  keyListSprite.appendChild(createCss2Button(`btnView${key}`, ``, evt => {
5018
5059
  keyList.forEach(keyx => {
@@ -5146,6 +5187,11 @@ const preconditionInit = () => {
5146
5187
  .replace(/[\t\n]/g, ``), 0, 15, g_cssObj.flex_centering),
5147
5188
 
5148
5189
  createDivCss2Label(`lblPrecondView`, viewKeyStorage(`g_rootObj`), g_lblPosObj.lblPrecondView),
5190
+ createCss2Button(`btnPrecondView`, g_lblNameObj.b_copyStorage, () =>
5191
+ copyTextToClipboard(
5192
+ viewKeyStorage(g_settings.preconditions[g_settings.preconditionNum * numOfPrecs + g_settings.preconditionNumSub], ``, false),
5193
+ g_msgInfoObj.I_0007),
5194
+ g_lblPosObj.btnPrecondView, g_cssObj.button_Default, g_cssObj.button_ON),
5149
5195
  );
5150
5196
  setUserSelect($id(`lblPrecondView`), `text`);
5151
5197
 
@@ -5175,6 +5221,7 @@ const preconditionInit = () => {
5175
5221
  }
5176
5222
  lblPrecondView.innerHTML = viewKeyStorage(g_settings.preconditions[g_settings.preconditionNum * numOfPrecs + j]);
5177
5223
  lblPrecondView.scrollTop = 0;
5224
+ g_settings.preconditionNumSub = j;
5178
5225
  evt.target.classList.replace(g_cssObj.button_Default, g_cssObj.button_Reset);
5179
5226
  }, {
5180
5227
  x: g_btnX() + g_btnWidth((j % (numOfPrecs / 2)) / (numOfPrecs / 2 + 1)),
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2025/03/02 (v40.1.0)
8
+ * Revised : 2025/03/08 (v40.3.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -283,6 +283,9 @@ const updateWindowSiz = () => {
283
283
  btnKeyStorage: {
284
284
  x: g_btnX(1) - 140, y: 100 + g_sHeight / 4 + 10, w: 70, h: 20, siz: 16,
285
285
  },
286
+ btnPrecondView: {
287
+ x: g_btnX(1) - 90, y: 110, w: 70, h: 20, siz: 16,
288
+ },
286
289
 
287
290
  /** 設定画面 */
288
291
  btnBack: {
@@ -785,6 +788,18 @@ const g_escapeStr = {
785
788
  [`all[]`, `sumData(g_detailObj.arrowCnt[{0}]) + sumData(g_detailObj.frzCnt[{0}])`],
786
789
  [`maxlife[]`, `g_headerObj.maxLifeVal`],
787
790
  ],
791
+ editorKey: [
792
+ [`ArrowLeft`, `KeyU`],
793
+ [`ArrowDown`, `KeyI`],
794
+ [`ArrowUp`, `Digit8`],
795
+ [`ArrowRight`, `KeyO`],
796
+ [`Space`, `KeyG`],
797
+ [`KeyB`, `KeyH`],
798
+ [`Enter`, `BackSlash`],
799
+ [`ShiftLeft`, `KeyZ`],
800
+ [`ShiftRight`, `Slash`],
801
+ [`Tab`, `KeyQ`],
802
+ ]
788
803
  };
789
804
 
790
805
  /** 設定・オプション画面用共通 */
@@ -1156,8 +1171,9 @@ const g_settings = {
1156
1171
  settingWindowNum: 0,
1157
1172
 
1158
1173
  preconditions: [`g_rootObj`, `g_headerObj`, `g_keyObj`, `g_scoreObj`, `g_workObj`,
1159
- `g_detailObj`, `g_stateObj`, `g_attrObj`],
1174
+ `g_detailObj`, `g_stateObj`, `g_attrObj`, `g_editorTmp`],
1160
1175
  preconditionNum: 0,
1176
+ preconditionNumSub: 0,
1161
1177
  };
1162
1178
 
1163
1179
  g_settings.volumeNum = g_settings.volumes.length - 1;
@@ -2487,6 +2503,7 @@ const g_keyObj = {
2487
2503
  dfPtnNum: 0,
2488
2504
 
2489
2505
  minKeyCtrlNum: 2,
2506
+ defaultKeyList: [],
2490
2507
 
2491
2508
  // キー別ヘッダー
2492
2509
  // - 譜面データ中に出てくる矢印(ノーツ)の種類と順番(ステップゾーン表示順)を管理する
@@ -3023,6 +3040,11 @@ const g_keyObj = {
3023
3040
  // g_keyObj.defaultProp の上書きを禁止
3024
3041
  Object.defineProperty(g_keyObj, `defaultProp`, { writable: false });
3025
3042
 
3043
+ // 既定のキー定義リストを動的に作成
3044
+ Object.keys(g_keyObj)
3045
+ .filter(key => key.startsWith(g_keyObj.defaultProp) && key.endsWith(`_0`))
3046
+ .forEach(key => g_keyObj.defaultKeyList.push(key.split(`_`)[0].slice(g_keyObj.defaultProp.length)));
3047
+
3026
3048
  // キーパターンのコピーリスト
3027
3049
  // ・コピー先:コピー元の順に指定する
3028
3050
  // ・上から順に処理する
@@ -3157,6 +3179,8 @@ g_keycons.groups.forEach(type => {
3157
3179
  tmpName.forEach(property => g_keyObj[`${property.slice(0, -2)}`] = g_keyObj[property].concat());
3158
3180
  });
3159
3181
 
3182
+ const g_editorTmp = {};
3183
+
3160
3184
  // 特殊キーのコピー種 (simple: 代入、multiple: 配列ごと代入)
3161
3185
  // 後でプロパティ削除に影響するため、先頭文字が全く同じ場合は長い方を先に定義する (例: divMax, div)
3162
3186
  const g_keyCopyLists = {
@@ -3447,6 +3471,7 @@ const g_lang_msgInfoObj = {
3447
3471
  I_0004: `musicUrlが設定されていないため、無音モードで再生します`,
3448
3472
  I_0005: `正規のミラー譜面で無いため、ハイスコアは保存されません`,
3449
3473
  I_0006: `ローカルストレージ情報をクリップボードにコピーしました!`,
3474
+ I_0007: `オブジェクト情報をクリップボードにコピーしました!`,
3450
3475
  },
3451
3476
  En: {
3452
3477
  W_0001: `Your browser is not guaranteed to work.<br>
@@ -3501,6 +3526,7 @@ const g_lang_msgInfoObj = {
3501
3526
  I_0004: `Play in silence mode because "musicUrl" is not set`,
3502
3527
  I_0005: `Highscore is not saved because not a regular mirrored chart.`,
3503
3528
  I_0006: `Local storage information copied to clipboard!`,
3529
+ I_0007: `Object information copied to clipboard!`,
3504
3530
  },
3505
3531
  };
3506
3532
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "40.2.0",
3
+ "version": "40.3.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "index.js",
6
6
  "scripts": {