danoniplus 47.0.1 → 47.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/04/20
7
+ * Revised : 2026/04/21
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 47.0.1`;
12
- const g_revisedDate = `2026/04/20`;
11
+ const g_version = `Ver 47.1.0`;
12
+ const g_revisedDate = `2026/04/21`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -2731,6 +2731,7 @@ const initialControl = async () => {
2731
2731
 
2732
2732
  // 譜面ヘッダー、特殊キー情報の読込
2733
2733
  Object.assign(g_headerObj, headerConvert(g_rootObj));
2734
+ g_headerObj.undefinedKeyListFinal = [];
2734
2735
  const importKeysData = _data => {
2735
2736
  keysConvert(dosConvert(_data));
2736
2737
  g_headerObj.undefinedKeyLists = g_headerObj.undefinedKeyLists.filter(key => g_keyObj[`${g_keyObj.defaultProp}${key}_0`] === undefined);
@@ -2744,6 +2745,20 @@ const initialControl = async () => {
2744
2745
  keyExtraList: makeDedupliArray(g_headerObj.undefinedKeyLists, g_rootObj.keyExtraList?.split(`,`)),
2745
2746
  });
2746
2747
 
2748
+ // キー定義でエラーになる場合は強制的にデフォルトキーへ変更して続行
2749
+ let hasUndefinedKey = false;
2750
+ for (let j = 0; j < g_headerObj.keyLabels.length; j++) {
2751
+ if (g_headerObj.undefinedKeyListFinal.includes(g_headerObj.keyLabels[j])) {
2752
+ g_headerObj.keyLists = g_headerObj.keyLists.filter(key => key !== g_headerObj.keyLabels[j]);
2753
+ g_headerObj.keyLabels[j] = g_keyObj.initKeyLabel;
2754
+ hasUndefinedKey = true;
2755
+ }
2756
+ }
2757
+ if (hasUndefinedKey) {
2758
+ g_headerObj.keyLists = makeDedupliArray(g_headerObj.keyLists, [g_keyObj.initKeyLabel])
2759
+ .sort((a, b) => parseInt(a) - parseInt(b));
2760
+ }
2761
+
2747
2762
  // デフォルトのカラー・シャッフルグループ設定を退避
2748
2763
  g_keycons.groups.forEach(type =>
2749
2764
  Object.keys(g_keyObj).filter(val => val.startsWith(type))
@@ -4011,7 +4026,7 @@ const headerConvert = _dosObj => {
4011
4026
  obj.lifeInits.push(lifeData(`Init`, 25));
4012
4027
 
4013
4028
  // キー数
4014
- const keyLabel = difDetails[difpos.Key] || `7`;
4029
+ const keyLabel = difDetails[difpos.Key] || g_keyObj.initKeyLabel;
4015
4030
  obj.keyLabels.push(g_keyObj.keyTransPattern[keyLabel] ?? keyLabel);
4016
4031
 
4017
4032
  // 譜面名、制作者名
@@ -4031,7 +4046,7 @@ const headerConvert = _dosObj => {
4031
4046
  });
4032
4047
  } else {
4033
4048
  makeWarningWindow(g_msgInfoObj.E_0021);
4034
- obj.keyLabels = [`7`];
4049
+ obj.keyLabels = [g_keyObj.initKeyLabel];
4035
4050
  obj.difLabels = [`Normal`];
4036
4051
  obj.initSpeeds = [3.5];
4037
4052
  obj.lifeBorders = [`x`];
@@ -5300,126 +5315,132 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
5300
5315
  g_keyObj.minPatterns = 1;
5301
5316
  g_keyObj.dfPtnNum = 0;
5302
5317
 
5303
- // キーパターンの追記 (appendX)
5304
- if (setBoolVal(_dosObj[`append${newKey}`])) {
5305
- for (let j = 0; ; j++) {
5306
- if (g_keyObj[`${g_keyObj.defaultProp}${newKey}_${j}`] === undefined) {
5307
- break;
5318
+ try {
5319
+
5320
+ // キーパターンの追記 (appendX)
5321
+ if (setBoolVal(_dosObj[`append${newKey}`])) {
5322
+ for (let j = 0; ; j++) {
5323
+ if (g_keyObj[`${g_keyObj.defaultProp}${newKey}_${j}`] === undefined) {
5324
+ break;
5325
+ }
5326
+ g_keyObj.dfPtnNum++;
5308
5327
  }
5309
- g_keyObj.dfPtnNum++;
5310
5328
  }
5311
- }
5312
- const dfPtnNum = g_keyObj.dfPtnNum;
5329
+ const dfPtnNum = g_keyObj.dfPtnNum;
5313
5330
 
5314
- // キーの名前 (keyNameX)
5315
- g_keyObj[`keyName${newKey}`] = _dosObj[`keyName${newKey}`]?.split(`,`) ?? [newKey, `key`];
5331
+ // キーの名前 (keyNameX)
5332
+ g_keyObj[`keyName${newKey}`] = _dosObj[`keyName${newKey}`]?.split(`,`) ?? [newKey, `key`];
5316
5333
 
5317
- // キーの最小横幅 (minWidthX)
5318
- g_keyObj[`minWidth${newKey}`] = _dosObj[`minWidth${newKey}`] ?? g_keyObj[`minWidth${newKey}`] ?? g_keyObj.minWidthDefault;
5334
+ // キーの最小横幅 (minWidthX)
5335
+ g_keyObj[`minWidth${newKey}`] = _dosObj[`minWidth${newKey}`] ?? g_keyObj[`minWidth${newKey}`] ?? g_keyObj.minWidthDefault;
5319
5336
 
5320
- // 移動ロック (movLockX)
5321
- g_keyObj[`movLock${newKey}`] = setBoolVal(_dosObj[`movLock${newKey}`] ?? g_keyObj[`movLock${newKey}`], false);
5337
+ // 移動ロック (movLockX)
5338
+ g_keyObj[`movLock${newKey}`] = setBoolVal(_dosObj[`movLock${newKey}`] ?? g_keyObj[`movLock${newKey}`], false);
5322
5339
 
5323
- // 位置マニュアル化 (initManualX)
5324
- g_keyObj[`initManual${newKey}`] = setBoolVal(_dosObj[`initManual${newKey}`] ?? g_keyObj[`initManual${newKey}`], false);
5340
+ // 位置マニュアル化 (initManualX)
5341
+ g_keyObj[`initManual${newKey}`] = setBoolVal(_dosObj[`initManual${newKey}`] ?? g_keyObj[`initManual${newKey}`], false);
5325
5342
 
5326
- // キーコンフィグ (keyCtrlX_Y)
5327
- g_keyObj.minPatterns = newKeyMultiParam(newKey, `keyCtrl`, toKeyCtrlArray, {
5328
- errCd: `E_0104`, baseCopyFlg: true,
5329
- });
5343
+ // キーコンフィグ (keyCtrlX_Y)
5344
+ g_keyObj.minPatterns = newKeyMultiParam(newKey, `keyCtrl`, toKeyCtrlArray, {
5345
+ errCd: `E_0104`, baseCopyFlg: true,
5346
+ });
5330
5347
 
5331
- // 読込変数の接頭辞 (charaX_Y)
5332
- newKeyMultiParam(newKey, `chara`, toString);
5348
+ // 読込変数の接頭辞 (charaX_Y)
5349
+ newKeyMultiParam(newKey, `chara`, toString);
5333
5350
 
5334
- // 矢印色パターン (colorX_Y)
5335
- newKeyTripleParam(newKey, `color`);
5351
+ // 矢印色パターン (colorX_Y)
5352
+ newKeyTripleParam(newKey, `color`);
5336
5353
 
5337
- // 矢印の回転量指定、キャラクタパターン (stepRtnX_Y)
5338
- newKeyTripleParam(newKey, `stepRtn`);
5354
+ // 矢印の回転量指定、キャラクタパターン (stepRtnX_Y)
5355
+ newKeyTripleParam(newKey, `stepRtn`);
5339
5356
 
5340
- // 各キーの区切り位置 (divX_Y)
5341
- _dosObj[`div${newKey}`]?.split(`$`).forEach((tmpDiv, k) => {
5342
- const tmpDivPtn = tmpDiv.split(`,`);
5343
- const ptnName = `${newKey}_${k + dfPtnNum}`;
5357
+ // 各キーの区切り位置 (divX_Y)
5358
+ _dosObj[`div${newKey}`]?.split(`$`).forEach((tmpDiv, k) => {
5359
+ const tmpDivPtn = tmpDiv.split(`,`);
5360
+ const ptnName = `${newKey}_${k + dfPtnNum}`;
5344
5361
 
5345
- if (g_keyObj[`div${tmpDivPtn[0]}`] !== undefined) {
5346
- // 既定キーパターンが指定された場合、存在すればその値を適用
5347
- g_keyObj[`div${ptnName}`] = g_keyObj[`div${tmpDivPtn[0]}`];
5348
- g_keyObj[`divMax${ptnName}`] = setVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined, C_TYP_FLOAT);
5349
- } else if (!hasVal(tmpDivPtn[0]) && setIntVal(g_keyObj[`div${ptnName}`], -1) !== -1) {
5350
- // カスタムキー側のdivXが未定義だが、すでに初期設定で定義済みの場合はスキップ
5351
- return;
5352
- } else {
5353
- // それ以外の場合は指定された値を適用(未指定時はその後で指定)
5354
- g_keyObj[`div${ptnName}`] = setVal(tmpDivPtn[0], undefined, C_TYP_NUMBER);
5355
- g_keyObj[`divMax${ptnName}`] = setVal(getKeyPosNum(tmpDivPtn[1], g_keyObj[`div${ptnName}`]), undefined, C_TYP_FLOAT);
5356
- }
5357
- });
5362
+ if (g_keyObj[`div${tmpDivPtn[0]}`] !== undefined) {
5363
+ // 既定キーパターンが指定された場合、存在すればその値を適用
5364
+ g_keyObj[`div${ptnName}`] = g_keyObj[`div${tmpDivPtn[0]}`];
5365
+ g_keyObj[`divMax${ptnName}`] = setVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined, C_TYP_FLOAT);
5366
+ } else if (!hasVal(tmpDivPtn[0]) && setIntVal(g_keyObj[`div${ptnName}`], -1) !== -1) {
5367
+ // カスタムキー側のdivXが未定義だが、すでに初期設定で定義済みの場合はスキップ
5368
+ return;
5369
+ } else {
5370
+ // それ以外の場合は指定された値を適用(未指定時はその後で指定)
5371
+ g_keyObj[`div${ptnName}`] = setVal(tmpDivPtn[0], undefined, C_TYP_NUMBER);
5372
+ g_keyObj[`divMax${ptnName}`] = setVal(getKeyPosNum(tmpDivPtn[1], g_keyObj[`div${ptnName}`]), undefined, C_TYP_FLOAT);
5373
+ }
5374
+ });
5358
5375
 
5359
- // ステップゾーン位置 (posX_Y)
5360
- newKeyMultiParam(newKey, `pos`, toFloat, {
5361
- loopFunc: (k, keyheader) => {
5362
- g_keyObj[`${keyheader}_${k + dfPtnNum}`].forEach((val, j) =>
5363
- g_keyObj[`${keyheader}_${k + dfPtnNum}`][j] = getKeyPosNum(String(val), g_keyObj[`div${newKey}_${k + dfPtnNum}`]));
5364
- },
5365
- });
5376
+ // ステップゾーン位置 (posX_Y)
5377
+ newKeyMultiParam(newKey, `pos`, toFloat, {
5378
+ loopFunc: (k, keyheader) => {
5379
+ g_keyObj[`${keyheader}_${k + dfPtnNum}`].forEach((val, j) =>
5380
+ g_keyObj[`${keyheader}_${k + dfPtnNum}`][j] = getKeyPosNum(String(val), g_keyObj[`div${newKey}_${k + dfPtnNum}`]));
5381
+ },
5382
+ });
5366
5383
 
5367
- // charaX_Y, posX_Y, keyGroupX_Y, divX_Y, divMaxX_Yが未指定の場合はkeyCtrlX_Yを元に適用
5368
- for (let k = 0; k < g_keyObj.minPatterns; k++) {
5369
- setKeyDfVal(`${newKey}_${k + dfPtnNum}`);
5370
- }
5384
+ // charaX_Y, posX_Y, keyGroupX_Y, divX_Y, divMaxX_Yが未指定の場合はkeyCtrlX_Yを元に適用
5385
+ for (let k = 0; k < g_keyObj.minPatterns; k++) {
5386
+ setKeyDfVal(`${newKey}_${k + dfPtnNum}`);
5387
+ }
5371
5388
 
5372
- // ステップゾーン間隔 (blankX_Y)
5373
- newKeySingleParam(newKey, `blank`, C_TYP_FLOAT, g_keyObj.blank_def);
5389
+ // ステップゾーン間隔 (blankX_Y)
5390
+ newKeySingleParam(newKey, `blank`, C_TYP_FLOAT, g_keyObj.blank_def);
5374
5391
 
5375
- // 矢印群の倍率 (scaleX_Y)
5376
- newKeySingleParam(newKey, `scale`, C_TYP_FLOAT, g_keyObj.scale_def);
5392
+ // 矢印群の倍率 (scaleX_Y)
5393
+ newKeySingleParam(newKey, `scale`, C_TYP_FLOAT, g_keyObj.scale_def);
5377
5394
 
5378
- // プレイ中ショートカット:リトライ (keyRetryX_Y)
5379
- newKeySingleParam(newKey, `keyRetry`, C_TYP_STRING, C_KEY_RETRY);
5395
+ // プレイ中ショートカット:リトライ (keyRetryX_Y)
5396
+ newKeySingleParam(newKey, `keyRetry`, C_TYP_STRING, C_KEY_RETRY);
5380
5397
 
5381
- // プレイ中ショートカット:タイトルバック (keyTitleBackX_Y)
5382
- newKeySingleParam(newKey, `keyTitleBack`, C_TYP_STRING, C_KEY_TITLEBACK);
5398
+ // プレイ中ショートカット:タイトルバック (keyTitleBackX_Y)
5399
+ newKeySingleParam(newKey, `keyTitleBack`, C_TYP_STRING, C_KEY_TITLEBACK);
5383
5400
 
5384
- // 別キーフラグ (transKeyX_Y)
5385
- newKeySingleParam(newKey, `transKey`, C_TYP_STRING, ``);
5401
+ // 別キーフラグ (transKeyX_Y)
5402
+ newKeySingleParam(newKey, `transKey`, C_TYP_STRING, ``);
5386
5403
 
5387
- // フラットモード (flatModeX_Y)
5388
- newKeySingleParam(newKey, `flatMode`, C_TYP_BOOLEAN, false);
5404
+ // フラットモード (flatModeX_Y)
5405
+ newKeySingleParam(newKey, `flatMode`, C_TYP_BOOLEAN, false);
5389
5406
 
5390
- // シャッフルグループ (shuffleX_Y)
5391
- newKeyTripleParam(newKey, `shuffle`);
5407
+ // シャッフルグループ (shuffleX_Y)
5408
+ newKeyTripleParam(newKey, `shuffle`);
5392
5409
 
5393
- // キーグループ (keyGroupX_Y)
5394
- newKeyMultiParam(newKey, `keyGroup`, toSplitArrayStr);
5410
+ // キーグループ (keyGroupX_Y)
5411
+ newKeyMultiParam(newKey, `keyGroup`, toSplitArrayStr);
5395
5412
 
5396
- // キーグループの表示制御 (keyGroupOrderX_Y)
5397
- newKeyMultiParam(newKey, `keyGroupOrder`, toString);
5413
+ // キーグループの表示制御 (keyGroupOrderX_Y)
5414
+ newKeyMultiParam(newKey, `keyGroupOrder`, toString);
5398
5415
 
5399
- // スクロールパターン (scrollX_Y)
5400
- // |scroll(newKey)=Cross::1,1,-1,-1,-1,1,1/Split::1,1,1,-1,-1,-1,-1$...|
5401
- newKeyPairParam(newKey, `scroll`, `scrollDir`, C_FLG_HYPHEN, 1);
5416
+ // スクロールパターン (scrollX_Y)
5417
+ // |scroll(newKey)=Cross::1,1,-1,-1,-1,1,1/Split::1,1,1,-1,-1,-1,-1$...|
5418
+ newKeyPairParam(newKey, `scroll`, `scrollDir`, C_FLG_HYPHEN, 1);
5402
5419
 
5403
- // アシストパターン (assistX_Y)
5404
- // |assist(newKey)=Onigiri::0,0,0,0,0,1/AA::0,0,0,1,1,1$...|
5405
- newKeyPairParam(newKey, `assist`, `assistPos`);
5420
+ // アシストパターン (assistX_Y)
5421
+ // |assist(newKey)=Onigiri::0,0,0,0,0,1/AA::0,0,0,1,1,1$...|
5422
+ newKeyPairParam(newKey, `assist`, `assistPos`);
5406
5423
 
5407
- // レーンごとの割当レイヤーグループ (layerGroupX_Y)
5408
- newKeyMultiParam(newKey, `layerGroup`, toInt);
5424
+ // レーンごとの割当レイヤーグループ (layerGroupX_Y)
5425
+ newKeyMultiParam(newKey, `layerGroup`, toInt);
5409
5426
 
5410
- // レイヤーごとのアニメーション情報 (layerTransX_Y)
5411
- if (hasVal(_dosObj[`layerTrans${newKey}`])) {
5412
- _dosObj[`layerTrans${newKey}`] = _dosObj[`layerTrans${newKey}`]?.replaceAll(`,`, `___`);
5413
- newKeyMultiParam(newKey, `layerTrans`, toSplitArrayStr, {
5414
- loopFunc: (k, keyheader) => {
5415
- g_keyObj[`${keyheader}_${k + dfPtnNum}`][0] = g_keyObj[`${keyheader}_${k + dfPtnNum}`]?.[0]?.map(val => val.replaceAll(`___`, `,`));
5416
- },
5417
- });
5418
- }
5427
+ // レイヤーごとのアニメーション情報 (layerTransX_Y)
5428
+ if (hasVal(_dosObj[`layerTrans${newKey}`])) {
5429
+ _dosObj[`layerTrans${newKey}`] = _dosObj[`layerTrans${newKey}`]?.replaceAll(`,`, `___`);
5430
+ newKeyMultiParam(newKey, `layerTrans`, toSplitArrayStr, {
5431
+ loopFunc: (k, keyheader) => {
5432
+ g_keyObj[`${keyheader}_${k + dfPtnNum}`][0] = g_keyObj[`${keyheader}_${k + dfPtnNum}`]?.[0]?.map(val => val.replaceAll(`___`, `,`));
5433
+ },
5434
+ });
5435
+ }
5419
5436
 
5420
- // keyRetry, keyTitleBackのキー名をキーコードに変換
5421
- const keyTypePatterns = Object.keys(g_keyObj).filter(val => val.startsWith(`keyRetry${newKey}`) || val.startsWith(`keyTitleBack${newKey}`));
5422
- keyTypePatterns.forEach(name => g_keyObj[name] = getKeyCtrlVal(g_keyObj[name]));
5437
+ // keyRetry, keyTitleBackのキー名をキーコードに変換
5438
+ const keyTypePatterns = Object.keys(g_keyObj).filter(val => val.startsWith(`keyRetry${newKey}`) || val.startsWith(`keyTitleBack${newKey}`));
5439
+ keyTypePatterns.forEach(name => g_keyObj[name] = getKeyCtrlVal(g_keyObj[name]));
5440
+ } catch (e) {
5441
+ g_headerObj.undefinedKeyListFinal.push(newKey);
5442
+ console.warn(`Error in key pattern conversion: ${newKey}`, e);
5443
+ }
5423
5444
  });
5424
5445
 
5425
5446
  return keyExtraList;
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/04/19 (v47.0.0)
8
+ * Revised : 2026/04/21 (v47.1.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -3118,6 +3118,7 @@ const g_keyObj = {
3118
3118
 
3119
3119
  minKeyCtrlNum: 2,
3120
3120
  defaultKeyList: [],
3121
+ initKeyLabel: `7`,
3121
3122
 
3122
3123
  // キー別ヘッダー
3123
3124
  // - 譜面データ中に出てくる矢印(ノーツ)の種類と順番(ステップゾーン表示順)を管理する
@@ -4288,7 +4289,8 @@ const g_lang_msgInfoObj = {
4288
4289
  E_0051: `Displayオプションのデフォルト設定(XXXXChainOFF)で、<br>指定できない組み合わせが設定されています。(E-0051)`,
4289
4290
 
4290
4291
  E_0104: `新しいキー:{0}の[keyCtrl]が未定義です。(E-0104)<br>
4291
- |keyCtrl{0}=S,D,E/R,F,Space,J,M/Comma,K,L|`,
4292
+ |keyCtrl{0}=S,D,E/R,F,Space,J,M/Comma,K,L|<br>
4293
+ 未定義のキーは7keyに割り当てられます。`,
4292
4294
 
4293
4295
  E_0201: `色変化データで指定した色変化対象が存在しません。[pattern={0}] (E-0201)`,
4294
4296
 
@@ -4336,7 +4338,8 @@ const g_lang_msgInfoObj = {
4336
4338
  E_0051: `In the default setting (XXXXChainOFF) of the Display option, <br>a combination that cannot be specified is set. (E-0051)`,
4337
4339
 
4338
4340
  E_0104: `New key: {0} [keyCtrl] is not set. (E-0104)<br>
4339
- |keyCtrl{0}=S,D,E/R,F,Space,J,M/Comma,K,L|`,
4341
+ |keyCtrl{0}=S,D,E/R,F,Space,J,M/Comma,K,L|<br>
4342
+ Undefined keymode is assigned to 7key.`,
4340
4343
 
4341
4344
  E_0201: `The color change target specified in the color change data does not exist. [pattern={0}] (E-0201)`,
4342
4345
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "47.0.1",
3
+ "version": "47.1.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "./js/danoni_main.js",
6
6
  "jsdelivr": "./js/danoni_main.js",