danoniplus 32.6.1 → 32.7.1

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 : 2023/07/08
7
+ * Revised : 2023/08/14
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 32.6.1`;
12
- const g_revisedDate = `2023/07/08`;
11
+ const g_version = `Ver 32.7.1`;
12
+ const g_revisedDate = `2023/08/14`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -348,7 +348,7 @@ const hasArrayList = (_data, _length = 1) => _data !== undefined && _data.length
348
348
  * 改行コード区切りの配列展開
349
349
  * @param {string} _str
350
350
  */
351
- const splitLF = _str => _str.split(`\r`).join(`\n`).split(`\n`);
351
+ const splitLF = _str => _str?.split(`\r`).join(`\n`).split(`\n`);
352
352
 
353
353
  /**
354
354
  * 改行コード区切りを本来の区切り文字に変換して配列展開
@@ -356,7 +356,7 @@ const splitLF = _str => _str.split(`\r`).join(`\n`).split(`\n`);
356
356
  * @param {string} _str
357
357
  * @param {string} _delim
358
358
  */
359
- const splitLF2 = (_str, _delim = `$`) => splitLF(_str).filter(val => val !== ``).join(_delim).split(_delim);
359
+ const splitLF2 = (_str, _delim = `$`) => splitLF(_str)?.filter(val => val !== ``).join(_delim).split(_delim);
360
360
 
361
361
  /**
362
362
  * 重複を排除した配列の生成
@@ -2462,6 +2462,26 @@ const calcLevel = _scoreObj => {
2462
2462
  };
2463
2463
  };
2464
2464
 
2465
+ /**
2466
+ * ロケールを含んだヘッダーの優先度設定
2467
+ * @param {object} _obj
2468
+ * @param {...any} _params
2469
+ */
2470
+ const getHeader = (_obj, ..._params) => {
2471
+ let headerLocale, headerDf;
2472
+ Object.keys(_params).forEach(j => {
2473
+ headerLocale ??= _obj[`${_params[j]}${g_localeObj.val}`];
2474
+ headerDf ??= _obj[_params[j]];
2475
+ });
2476
+ return headerLocale ?? headerDf;
2477
+ };
2478
+
2479
+ /**
2480
+ * ヘッダー名の互換設定
2481
+ * @param {string} _param
2482
+ */
2483
+ const getHname = _param => [_param, _param.toLowerCase()];
2484
+
2465
2485
  /**
2466
2486
  * 譜面ヘッダーの分解(スキン、jsファイルなどの設定)
2467
2487
  * @param {object} _dosObj
@@ -2495,11 +2515,11 @@ const preheaderConvert = _dosObj => {
2495
2515
  setJsFiles(tmpSkinTypes, C_DIR_SKIN, `skin`);
2496
2516
 
2497
2517
  // 外部jsファイルの指定
2498
- const tmpCustomjs = _dosObj.customjs ?? g_presetObj.customJs ?? C_JSF_CUSTOM;
2518
+ const tmpCustomjs = getHeader(_dosObj, ...getHname(`customJs`)) ?? g_presetObj.customJs ?? C_JSF_CUSTOM;
2499
2519
  setJsFiles(tmpCustomjs.replaceAll(`*`, g_presetObj.customJs).split(`,`), C_DIR_JS);
2500
2520
 
2501
2521
  // 外部cssファイルの指定
2502
- const tmpCustomcss = _dosObj.customcss ?? g_presetObj.customCss ?? ``;
2522
+ const tmpCustomcss = getHeader(_dosObj, ...getHname(`customCss`)) ?? g_presetObj.customCss ?? ``;
2503
2523
  setJsFiles(tmpCustomcss.replaceAll(`*`, g_presetObj.customCss).split(`,`), C_DIR_CSS);
2504
2524
 
2505
2525
  // デフォルト曲名表示、背景、Ready表示の利用有無
@@ -2524,13 +2544,6 @@ const headerConvert = _dosObj => {
2524
2544
  // ヘッダー群の格納先
2525
2545
  const obj = {};
2526
2546
 
2527
- /**
2528
- * ロケールを含んだヘッダーの取得
2529
- * @param {object} _obj
2530
- * @param {string} _param
2531
- */
2532
- const getHeader = (_obj, _param) => _obj[`${_param}${g_localeObj.val}`] ?? _obj[_param];
2533
-
2534
2547
  // フォントの設定
2535
2548
  obj.customFont = _dosObj.customFont ?? ``;
2536
2549
  g_headerObj.customFont = obj.customFont;
@@ -2919,29 +2932,30 @@ const headerConvert = _dosObj => {
2919
2932
  obj.readyHtml = _dosObj.readyHtml ?? ``;
2920
2933
 
2921
2934
  // デフォルト曲名表示のフォントサイズ
2922
- obj.titlesize = getHeader(_dosObj, `titlesize`) ?? ``;
2935
+ obj.titlesize = getHeader(_dosObj, ...getHname(`titleSize`)) ?? ``;
2923
2936
 
2924
2937
  // デフォルト曲名表示のフォント名
2925
2938
  // (使用例: |titlefont=Century,Meiryo UI|)
2926
2939
  obj.titlefonts = g_titleLists.defaultFonts.concat();
2927
- getHeader(_dosObj, `titlefont`)?.split(`$`).forEach((font, j) => obj.titlefonts[j] = `'${(font.replaceAll(`,`, `', '`))}'`);
2940
+ getHeader(_dosObj, ...getHname(`titleFont`))?.split(`$`).forEach((font, j) => obj.titlefonts[j] = `'${(font.replaceAll(`,`, `', '`))}'`);
2928
2941
  if (obj.titlefonts[1] === undefined) {
2929
2942
  obj.titlefonts[1] = obj.titlefonts[0];
2930
2943
  }
2931
2944
 
2932
2945
  // デフォルト曲名表示, 背景矢印のグラデーション指定css
2933
- g_titleLists.grdList.forEach(_name => {
2934
- obj[`${_name}s`] = [];
2935
- if (hasVal(_dosObj[_name])) {
2936
- const tmpTitlegrd = _dosObj[_name].replaceAll(`,`, `:`);
2937
- obj[`${_name}s`] = tmpTitlegrd.split(`$`);
2938
- obj[`${_name}`] = obj[`${_name}s`][0] ?? ``;
2946
+ [`titlegrd`, `titleArrowgrd`].forEach(_name => {
2947
+ const objName = `${_name.toLowerCase()}`;
2948
+ obj[`${objName}s`] = [];
2949
+ const tmpTitlegrd = getHeader(_dosObj, ...getHname(_name))?.replaceAll(`,`, `:`);
2950
+ if (hasVal(tmpTitlegrd)) {
2951
+ obj[`${objName}s`] = tmpTitlegrd.split(`$`);
2952
+ obj[`${objName}`] = obj[`${objName}s`][0] ?? ``;
2939
2953
  }
2940
2954
  });
2941
2955
 
2942
2956
  // デフォルト曲名表示の表示位置調整
2943
2957
  obj.titlepos = [[0, 0], [0, 0]];
2944
- getHeader(_dosObj, `titlepos`)?.split(`$`).forEach((pos, j) => obj.titlepos[j] = pos.split(`,`).map(x => parseFloat(x)));
2958
+ getHeader(_dosObj, ...getHname(`titlePos`))?.split(`$`).forEach((pos, j) => obj.titlepos[j] = pos.split(`,`).map(x => parseFloat(x)));
2945
2959
 
2946
2960
  // タイトル文字のアニメーション設定
2947
2961
  obj.titleAnimationName = [`leftToRight`];
@@ -2950,14 +2964,14 @@ const headerConvert = _dosObj => {
2950
2964
  obj.titleAnimationTimingFunction = [`ease`];
2951
2965
  obj.titleAnimationClass = [``];
2952
2966
 
2953
- _dosObj.titleanimation?.split(`$`).forEach((pos, j) => {
2967
+ getHeader(_dosObj, ...getHname(`titleAnimation`))?.split(`$`).forEach((pos, j) => {
2954
2968
  const titleAnimation = pos.split(`,`);
2955
2969
  obj.titleAnimationName[j] = setVal(titleAnimation[0], obj.titleAnimationName[0]);
2956
2970
  obj.titleAnimationDuration[j] = setVal(titleAnimation[1] / g_fps, obj.titleAnimationDuration[0], C_TYP_FLOAT);
2957
2971
  obj.titleAnimationDelay[j] = setVal(titleAnimation[2] / g_fps, obj.titleAnimationDelay[0], C_TYP_FLOAT);
2958
2972
  obj.titleAnimationTimingFunction[j] = setVal(titleAnimation[3], obj.titleAnimationName[3]);
2959
2973
  });
2960
- _dosObj.titleanimationclass?.split(`$`).forEach((animationClass, j) =>
2974
+ getHeader(_dosObj, ...getHname(`titleAnimationClass`))?.split(`$`).forEach((animationClass, j) =>
2961
2975
  obj.titleAnimationClass[j] = animationClass ?? ``);
2962
2976
 
2963
2977
  if (obj.titleAnimationName.length === 1) {
@@ -2969,7 +2983,7 @@ const headerConvert = _dosObj => {
2969
2983
  }
2970
2984
 
2971
2985
  // デフォルト曲名表示の複数行時の縦間隔
2972
- obj.titlelineheight = setIntVal(getHeader(_dosObj, `titlelineheight`), ``);
2986
+ obj.titlelineheight = setIntVal(getHeader(_dosObj, ...getHname(`titleLineHeight`)), ``);
2973
2987
 
2974
2988
  // フリーズアローの始点で通常矢印の判定を行うか(dotさんソース方式)
2975
2989
  obj.frzStartjdgUse = setBoolVal(_dosObj.frzStartjdgUse ?? g_presetObj.frzStartjdgUse);
@@ -3045,7 +3059,6 @@ const headerConvert = _dosObj => {
3045
3059
  // [フレーム数,階層,背景パス,class(CSSで別定義),X,Y,width,height,opacity,animationName,animationDuration]
3046
3060
  g_animationData.forEach(sprite => {
3047
3061
  obj[`${sprite}TitleData`] = [];
3048
- obj[`${sprite}TitleData`].length = 0;
3049
3062
  obj[`${sprite}TitleMaxDepth`] = -1;
3050
3063
 
3051
3064
  const dataList = [_dosObj[`${sprite}title${g_localeObj.val}_data`], _dosObj[`${sprite}title_data`]];
@@ -3068,7 +3081,7 @@ const headerConvert = _dosObj => {
3068
3081
  obj.resultMotionSet = setBoolVal(_dosObj.resultMotionSet, true);
3069
3082
 
3070
3083
  // 譜面明細の使用可否
3071
- const tmpDetails = _dosObj.scoreDetailUse?.split(`,`).filter(val => hasVal(val) && val !== `false`)
3084
+ const tmpDetails = getHeader(_dosObj, `scoreDetailUse`, `chartDetailUse`)?.split(`,`).filter(val => hasVal(val) && val !== `false`)
3072
3085
  .map(val => replaceStr(val, g_settings.scoreDetailTrans));
3073
3086
  g_settings.scoreDetails = g_settings.scoreDetailDefs.filter(val => tmpDetails?.includes(val) || tmpDetails === undefined);
3074
3087
 
@@ -3581,14 +3594,13 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
3581
3594
  const dfPtn = setIntVal(g_keyObj.dfPtnNum);
3582
3595
 
3583
3596
  if (hasVal(_dosObj[keyheader])) {
3584
- const tmpArray = splitLF2(_dosObj[keyheader]);
3585
- for (let k = 0; k < tmpArray.length; k++) {
3586
- if (existParam(tmpArray[k], `${keyheader}_${k + dfPtn}`)) {
3587
- continue;
3597
+ splitLF2(_dosObj[keyheader])?.forEach((tmpParam, k) => {
3598
+ if (existParam(tmpParam, `${keyheader}_${k + dfPtn}`)) {
3599
+ return;
3588
3600
  }
3589
3601
 
3590
3602
  let ptnCnt = 0;
3591
- tmpArray[k].split(`/`).forEach(list => {
3603
+ tmpParam.split(`/`).forEach(list => {
3592
3604
 
3593
3605
  const keyPtn = getKeyPtnName(list);
3594
3606
  if (list === ``) {
@@ -3617,7 +3629,7 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
3617
3629
  }
3618
3630
  });
3619
3631
  g_keyObj[`${keyheader}_${k + dfPtn}`] = structuredClone(g_keyObj[`${keyheader}_${k + dfPtn}_0`]);
3620
- }
3632
+ });
3621
3633
 
3622
3634
  } else if (g_keyObj[`${keyheader}_${dfPtn}_0`] === undefined) {
3623
3635
  // 特に指定が無い場合はkeyCtrlX_Yの配列長で決定
@@ -3663,39 +3675,36 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
3663
3675
  const keyheader = _name + _key;
3664
3676
  const dfPtn = setIntVal(g_keyObj.dfPtnNum);
3665
3677
 
3666
- if (_dosObj[keyheader] !== undefined) {
3667
- const tmpParams = splitLF2(_dosObj[keyheader]);
3668
- for (let k = 0; k < tmpParams.length; k++) {
3669
- const pairName = `${_pairName}${_key}_${k + dfPtn}`;
3670
- if (!hasVal(tmpParams[k])) {
3671
- continue;
3672
- }
3673
- g_keyObj[pairName] = {}
3678
+ splitLF2(_dosObj[keyheader])?.forEach((tmpParam, k) => {
3679
+ const pairName = `${_pairName}${_key}_${k + dfPtn}`;
3680
+ if (!hasVal(tmpParam)) {
3681
+ return;
3682
+ }
3683
+ g_keyObj[pairName] = {}
3674
3684
 
3675
- // デフォルト項目がある場合は先に定義
3676
- if (_defaultName !== ``) {
3677
- g_keyObj[pairName][_defaultName] = [...Array(g_keyObj[`${g_keyObj.defaultProp}${_key}_${k + dfPtn}`].length)].fill(_defaultVal);
3678
- }
3679
- tmpParams[k].split(`/`).forEach(pairs => {
3680
- const keyPtn = getKeyPtnName(pairs);
3681
- if (pairs === ``) {
3682
- } else if (g_keyObj[`${_pairName}${keyPtn}`] !== undefined) {
3683
- // 他のキーパターン指定時、該当があればプロパティを全コピー
3684
- Object.assign(g_keyObj[pairName], g_keyObj[`${_pairName}${keyPtn}`]);
3685
- } else {
3686
- // 通常の指定方法(例:|scroll8i=Cross::1,1,1,-,-,-,1,1/Split::1,1,1,1,-,-,-,-|)から取り込み
3687
- // 部分的にキーパターン指定があった場合は既存パターンを展開 (例: |scroll9j=Cross::1,7_0,1|)
3688
- const tmpParamPair = pairs.split(`::`);
3689
- g_keyObj[pairName][tmpParamPair[0]] =
3690
- makeBaseArray(tmpParamPair[1].split(`,`).map(n =>
3691
- g_keyObj[`${_pairName}${getKeyPtnName(n)}`] !== undefined ?
3692
- structuredClone(g_keyObj[`${_pairName}${getKeyPtnName(n)}`][tmpParamPair[0]]) :
3693
- [n === `-` ? -1 : parseInt(n, 10)]
3694
- ).flat(), g_keyObj[`${g_keyObj.defaultProp}${_key}_${k + dfPtn}`].length, _defaultVal);
3695
- }
3696
- });
3685
+ // デフォルト項目がある場合は先に定義
3686
+ if (_defaultName !== ``) {
3687
+ g_keyObj[pairName][_defaultName] = [...Array(g_keyObj[`${g_keyObj.defaultProp}${_key}_${k + dfPtn}`].length)].fill(_defaultVal);
3697
3688
  }
3698
- }
3689
+ tmpParam.split(`/`).forEach(pairs => {
3690
+ const keyPtn = getKeyPtnName(pairs);
3691
+ if (pairs === ``) {
3692
+ } else if (g_keyObj[`${_pairName}${keyPtn}`] !== undefined) {
3693
+ // 他のキーパターン指定時、該当があればプロパティを全コピー
3694
+ Object.assign(g_keyObj[pairName], g_keyObj[`${_pairName}${keyPtn}`]);
3695
+ } else {
3696
+ // 通常の指定方法(例:|scroll8i=Cross::1,1,1,-,-,-,1,1/Split::1,1,1,1,-,-,-,-|)から取り込み
3697
+ // 部分的にキーパターン指定があった場合は既存パターンを展開 (例: |scroll9j=Cross::1,7_0,1|)
3698
+ const tmpParamPair = pairs.split(`::`);
3699
+ g_keyObj[pairName][tmpParamPair[0]] =
3700
+ makeBaseArray(tmpParamPair[1]?.split(`,`).map(n =>
3701
+ g_keyObj[`${_pairName}${getKeyPtnName(n)}`] !== undefined ?
3702
+ structuredClone(g_keyObj[`${_pairName}${getKeyPtnName(n)}`][tmpParamPair[0]]) :
3703
+ [n === `-` ? -1 : parseInt(n, 10)]
3704
+ ).flat(), g_keyObj[`${g_keyObj.defaultProp}${_key}_${k + dfPtn}`].length, _defaultVal);
3705
+ }
3706
+ });
3707
+ });
3699
3708
  };
3700
3709
 
3701
3710
  // 対象キー毎に処理
@@ -4491,6 +4500,7 @@ const drawSpeedGraph = _scoreId => {
4491
4500
 
4492
4501
  const avgX = [0, 0];
4493
4502
  const avgSubX = [1, 1];
4503
+ const lineX = [125, 210];
4494
4504
  Object.keys(speedObj).forEach((speedType, j) => {
4495
4505
  context.beginPath();
4496
4506
  let preY;
@@ -4519,13 +4529,12 @@ const drawSpeedGraph = _scoreId => {
4519
4529
  context.strokeStyle = speedObj[speedType].strokeColor;
4520
4530
  context.stroke();
4521
4531
 
4522
- const lineX = (speedType === `speed`) ? 125 : 210;
4523
4532
  context.beginPath();
4524
- context.moveTo(lineX, 215);
4525
- context.lineTo(lineX + 25, 215);
4533
+ context.moveTo(lineX[j], 215);
4534
+ context.lineTo(lineX[j] + 25, 215);
4526
4535
  context.stroke();
4527
4536
  context.font = `${g_limitObj.difSelectorSiz}px ${getBasicFont()}`;
4528
- context.fillText(g_lblNameObj[`s_${speedType}`], lineX + 30, 218);
4537
+ context.fillText(g_lblNameObj[`s_${speedType}`], lineX[j] + 30, 218);
4529
4538
 
4530
4539
  updateScoreDetailLabel(`Speed`, `${speedType}S`, speedObj[speedType].cnt, j, g_lblNameObj[`s_${speedType}`]);
4531
4540
  updateScoreDetailLabel(`Speed`, `avgD${speedType}`, avgSubX[j] === 1 ? `----` : `${(avgSubX[j]).toFixed(2)}x`, j + 4, g_lblNameObj[`s_avgD${speedType}`]);
@@ -7229,22 +7238,8 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7229
7238
  * 矢印データの格納
7230
7239
  * @param {string} _data
7231
7240
  */
7232
- const storeArrowData = _data => {
7233
- let arrowData = [];
7234
-
7235
- if (hasVal(_data)) {
7236
- const tmpData = splitLF(_data).join(``);
7237
- if (tmpData !== undefined) {
7238
- arrowData = tmpData.split(`,`);
7239
- if (isNaN(parseFloat(arrowData[0]))) {
7240
- return [];
7241
- } else {
7242
- arrowData = arrowData.map(data => calcFrame(data)).sort((_a, _b) => _a - _b);
7243
- }
7244
- }
7245
- }
7246
- return arrowData;
7247
- };
7241
+ const storeArrowData = _data => hasVal(_data) ?
7242
+ splitLF(_data)?.join(``).split(`,`).filter(data => !isNaN(parseFloat(data))).map(data => calcFrame(data)).sort((_a, _b) => _a - _b) : [];
7248
7243
 
7249
7244
  for (let j = 0; j < keyNum; j++) {
7250
7245
 
@@ -8041,11 +8036,10 @@ const pushArrows = (_dataObj, _speedOnFrame, _motionOnFrame, _firstArrivalFrame)
8041
8036
  (cgArrays.includes(_type) ? _data[startNum][_j][0] === _data[startNum][_k][0] :
8042
8037
  _data[startNum][_j].depth === _data[startNum][_k].depth);
8043
8038
 
8044
- const fuzzyCheck = (_str, _list) => listMatching(_str, _list);
8045
8039
  const isExceptData = {
8046
- word: (_exceptList, _j) => fuzzyCheck(_data[startNum][_j][1], _exceptList.word),
8047
- back: (_exceptList, _j) => fuzzyCheck(_data[startNum][_j].animationName, _exceptList.back),
8048
- mask: (_exceptList, _j) => fuzzyCheck(_data[startNum][_j].animationName, _exceptList.mask),
8040
+ word: (_exceptList, _j) => listMatching(_data[startNum][_j][1], _exceptList.word),
8041
+ back: (_exceptList, _j) => listMatching(_data[startNum][_j].animationName, _exceptList.back),
8042
+ mask: (_exceptList, _j) => listMatching(_data[startNum][_j].animationName, _exceptList.mask),
8049
8043
  };
8050
8044
 
8051
8045
  const getLength = _list =>
@@ -8104,7 +8098,6 @@ const pushArrows = (_dataObj, _speedOnFrame, _motionOnFrame, _firstArrivalFrame)
8104
8098
 
8105
8099
  // 実際に処理させる途中変速配列を作成
8106
8100
  g_workObj.speedData = [];
8107
- g_workObj.speedData.length = 0;
8108
8101
  g_workObj.speedData.push(g_scoreObj.frameNum);
8109
8102
  g_workObj.speedData.push(_speedOnFrame[g_scoreObj.frameNum]);
8110
8103
 
@@ -9291,7 +9284,7 @@ const mainInit = _ => {
9291
9284
 
9292
9285
  frzOFF: (_j, _k, _cnt) => {
9293
9286
 
9294
- if (g_workObj.judgFrzCnt[_j] === _k - 1 && _cnt <= g_judgObj.frzJ[g_judgPosObj.sfsf]) {
9287
+ if (g_workObj.judgFrzCnt[_j] === _k - 1) {
9295
9288
  const prevFrzName = `frz${_j}_${g_workObj.judgFrzCnt[_j]}`;
9296
9289
  const prevFrz = g_attrObj[prevFrzName];
9297
9290
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2023/07/08 (v32.6.1)
8
+ * Revised : 2023/07/17 (v32.7.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -2313,9 +2313,6 @@ const g_titleLists = {
2313
2313
  /** タイトルのデフォルトフォント */
2314
2314
  defaultFonts: [`'メイリオ'`],
2315
2315
 
2316
- /** グラデーション関連初期リスト */
2317
- grdList: [`titlegrd`, `titlearrowgrd`],
2318
-
2319
2316
  /** タイトル用アニメーションの設定種 */
2320
2317
  animation: [`Name`, `Duration`, `Delay`, `TimingFunction`],
2321
2318
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "32.6.1",
3
+ "version": "32.7.1",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "index.js",
6
6
  "scripts": {