danoniplus 31.0.1 → 31.2.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 : 2023/03/22
7
+ * Revised : 2023/04/01
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 31.0.1`;
12
- const g_revisedDate = `2023/03/22`;
11
+ const g_version = `Ver 31.2.0`;
12
+ const g_revisedDate = `2023/04/01`;
13
13
  const g_alphaVersion = ``;
14
14
 
15
15
  // カスタム用バージョン (danoni_custom.js 等で指定可)
@@ -402,6 +402,39 @@ const makeBaseArray = (_array, _minLength, _defaultVal) => {
402
402
  return baseArray;
403
403
  };
404
404
 
405
+ /**
406
+ * 配列から上位N番目までに一致する位置を取得
407
+ *
408
+ * ex. 上位3番目 (_num = 3) の場合
409
+ * [1, 3, 2, 4, 6, 4, 5] -> [[4], [6], [3, 5]]
410
+ * [9, 6, 9, 9, 8, 7, 5] -> [[0, 2, 3]]
411
+ * @param {array} _array
412
+ * @param {number} _num
413
+ * @returns
414
+ */
415
+ const getMaxValIdxs = (_array, _num = 1) => {
416
+ const getMaxVal = (_a, _b) => Math.max(_a, _b);
417
+ let baseArray = _array.concat();
418
+ const maxIdxs = [];
419
+
420
+ for (let j = 0; j < _num; j++) {
421
+ maxIdxs[j] = [];
422
+ const maxVal = baseArray.reduce((a, b) => getMaxVal(a, b));
423
+ _array.map((val, idx) => {
424
+ if (val === maxVal) {
425
+ maxIdxs[j].push(idx);
426
+ }
427
+ });
428
+ baseArray = baseArray.filter(val => val < maxVal);
429
+
430
+ // 同率で上位N番目まで取得した場合は途中で終了
431
+ if (baseArray.length === 0 || maxIdxs.flat().length >= _num) {
432
+ break;
433
+ }
434
+ }
435
+ return maxIdxs;
436
+ };
437
+
405
438
  /**
406
439
  * 部分一致検索(リストのいずれかに合致、大小文字問わず)
407
440
  * @param {string} _str 検索文字
@@ -2199,7 +2232,7 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2199
2232
 
2200
2233
  // 譜面密度グラフ用のデータ作成
2201
2234
  const noteCnt = { arrow: [], frz: [] };
2202
- const densityData = [...Array(C_LEN_DENSITY_DIVISION)].fill(0);
2235
+ const densityData = [...Array(g_limitObj.densityDivision)].fill(0);
2203
2236
  let allData = 0;
2204
2237
 
2205
2238
  const types = [`arrow`, `frz`];
@@ -2214,7 +2247,7 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2214
2247
  if (isNaN(parseFloat(note))) {
2215
2248
  return;
2216
2249
  }
2217
- const point = Math.floor((note - firstArrowFrame) / playingFrame * C_LEN_DENSITY_DIVISION);
2250
+ const point = Math.floor((note - firstArrowFrame) / playingFrame * g_limitObj.densityDivision);
2218
2251
  if (point >= 0) {
2219
2252
  densityData[point]++;
2220
2253
  noteCnt[types[m]][j]++;
@@ -2227,13 +2260,13 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2227
2260
 
2228
2261
  fullData = fullData.filter(val => !isNaN(parseFloat(val))).sort((a, b) => a - b);
2229
2262
  let pushCnt = 1;
2230
- const density2PushData = [...Array(C_LEN_DENSITY_DIVISION)].fill(0);
2231
- const density3PushData = [...Array(C_LEN_DENSITY_DIVISION)].fill(0);
2263
+ const density2PushData = [...Array(g_limitObj.densityDivision)].fill(0);
2264
+ const density3PushData = [...Array(g_limitObj.densityDivision)].fill(0);
2232
2265
  fullData.forEach((note, j) => {
2233
2266
  if (fullData[j] === fullData[j + 1]) {
2234
2267
  pushCnt++;
2235
2268
  } else {
2236
- const point = Math.floor((note - firstArrowFrame) / playingFrame * C_LEN_DENSITY_DIVISION);
2269
+ const point = Math.floor((note - firstArrowFrame) / playingFrame * g_limitObj.densityDivision);
2237
2270
  if (point >= 0) {
2238
2271
  if (pushCnt >= 2) {
2239
2272
  density2PushData[point] += pushCnt;
@@ -2252,8 +2285,8 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2252
2285
 
2253
2286
  const storeDensity = _densityData => {
2254
2287
  const dataList = [];
2255
- for (let j = 0; j < C_LEN_DENSITY_DIVISION; j++) {
2256
- dataList.push(allData === 0 ? 0 : Math.round(_densityData[j] / allData * C_LEN_DENSITY_DIVISION * 10000) / 100);
2288
+ for (let j = 0; j < g_limitObj.densityDivision; j++) {
2289
+ dataList.push(allData === 0 ? 0 : Math.round(_densityData[j] / allData * g_limitObj.densityDivision * 10000) / 100);
2257
2290
  }
2258
2291
  return dataList;
2259
2292
  };
@@ -2270,7 +2303,7 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2270
2303
  g_detailObj.density2PushDiff[_scoreId] = diffArray(g_detailObj.density2PushData[_scoreId], g_detailObj.density3PushData[_scoreId]);
2271
2304
  g_detailObj.density3PushDiff[_scoreId] = g_detailObj.density3PushData[_scoreId].concat();
2272
2305
 
2273
- g_detailObj.maxDensity[_scoreId] = densityData.indexOf(Math.max.apply(null, densityData));
2306
+ g_detailObj.maxDensity[_scoreId] = getMaxValIdxs(densityData, g_limitObj.densityMaxVals).flat();
2274
2307
 
2275
2308
  g_detailObj.arrowCnt[_scoreId] = noteCnt.arrow.concat();
2276
2309
  g_detailObj.frzCnt[_scoreId] = noteCnt.frz.concat();
@@ -3184,15 +3217,22 @@ const resetBaseColorList = (_baseObj, _dosObj, { scoreId = `` } = {}) => {
3184
3217
 
3185
3218
  const obj = {};
3186
3219
  const scoreIdHeader = setScoreIdHeader(scoreId);
3220
+ const getRefData = (_header, _dataName) => {
3221
+ const data = _dosObj[`${_header}${_dataName}`];
3222
+ return data?.startsWith(_header) ? _dosObj[data] : data;
3223
+ }
3187
3224
 
3188
3225
  [``, `Shadow`].forEach(pattern => {
3189
- const _name = `set${pattern}Color${scoreIdHeader}`;
3190
- const _frzName = `frz${pattern}Color${scoreIdHeader}`;
3191
- const _arrowInit = `set${pattern}ColorInit`;
3192
- const _frzInit = `frz${pattern}ColorInit`;
3226
+ const _arrowCommon = `set${pattern}Color`;
3227
+ const _frzCommon = `frz${pattern}Color`;
3228
+
3229
+ const _name = `${_arrowCommon}${scoreIdHeader}`;
3230
+ const _frzName = `${_frzCommon}${scoreIdHeader}`;
3231
+ const _arrowInit = `${_arrowCommon}Init`;
3232
+ const _frzInit = `${_frzCommon}Init`;
3193
3233
 
3194
- const arrowColorTxt = _dosObj[_name] || _dosObj[`set${pattern}Color`];
3195
- const frzColorTxt = _dosObj[_frzName] || _dosObj[`frz${pattern}Color`];
3234
+ const arrowColorTxt = getRefData(_arrowCommon, scoreIdHeader) || _dosObj[_arrowCommon];
3235
+ const frzColorTxt = getRefData(_frzCommon, scoreIdHeader) || _dosObj[_frzCommon];
3196
3236
 
3197
3237
  // 矢印色
3198
3238
  Object.keys(_baseObj.dfColorgrdSet).forEach(type => {
@@ -4601,12 +4641,12 @@ const createOptionWindow = _sprite => {
4601
4641
  const canvas = document.querySelector(`#graphDensity`);
4602
4642
  const context = canvas.getContext(`2d`);
4603
4643
  drawBaseLine(context);
4604
- for (let j = 0; j < C_LEN_DENSITY_DIVISION; j++) {
4644
+ for (let j = 0; j < g_limitObj.densityDivision; j++) {
4605
4645
  context.beginPath();
4606
4646
  [``, `2Push`, `3Push`].forEach(val => {
4607
- context.fillStyle = (j === g_detailObj.maxDensity[_scoreId] ? g_graphColorObj[`max${val}`] : g_graphColorObj[`default${val}`]);
4608
- context.fillRect(16 * j * 16 / C_LEN_DENSITY_DIVISION + 30, 195 - 9 * g_detailObj[`density${val}Data`][_scoreId][j] / 10,
4609
- 15.5 * 16 / C_LEN_DENSITY_DIVISION, 9 * g_detailObj[`density${val}Diff`][_scoreId][j] / 10
4647
+ context.fillStyle = (g_detailObj.maxDensity[_scoreId].includes(j) ? g_graphColorObj[`max${val}`] : g_graphColorObj[`default${val}`]);
4648
+ context.fillRect(16 * j * 16 / g_limitObj.densityDivision + 30, 195 - 9 * g_detailObj[`density${val}Data`][_scoreId][j] / 10,
4649
+ 15.5 * 16 / g_limitObj.densityDivision, 9 * g_detailObj[`density${val}Diff`][_scoreId][j] / 10
4610
4650
  );
4611
4651
  });
4612
4652
  context.stroke();
@@ -7131,10 +7171,11 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7131
7171
  * @param {string} _footer
7132
7172
  */
7133
7173
  const setSpeedData = (_header, _scoreNo, _footer = `_data`) => {
7174
+ const dosSpeedData = getRefData(_header, `${_scoreNo}${_footer}`);
7134
7175
  const speedData = [];
7135
7176
 
7136
- if (hasVal(_dosObj[`${_header}${_scoreNo}${_footer}`]) && g_stateObj.d_speed === C_FLG_ON) {
7137
- const tmpArrayData = splitLF(_dosObj[`${_header}${_scoreNo}${_footer}`]);
7177
+ if (hasVal(dosSpeedData) && g_stateObj.d_speed === C_FLG_ON) {
7178
+ const tmpArrayData = splitLF(dosSpeedData);
7138
7179
 
7139
7180
  tmpArrayData.filter(data => hasVal(data)).forEach(tmpData => {
7140
7181
  const tmpSpeedData = tmpData.split(`,`);
@@ -7173,11 +7214,12 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7173
7214
  * @param {number} _scoreNo
7174
7215
  */
7175
7216
  const setColorData = (_header, _scoreNo) => {
7217
+ const dosColorData = getRefData(_header, `${_scoreNo}_data`);
7176
7218
  const colorData = [];
7177
7219
  const allFlg = (_header.charAt(0) === `a`);
7178
7220
 
7179
- if (hasVal(_dosObj[`${_header}${_scoreNo}_data`]) && g_stateObj.d_color === C_FLG_ON) {
7180
- const tmpArrayData = splitLF(_dosObj[`${_header}${_scoreNo}_data`]);
7221
+ if (hasVal(dosColorData) && g_stateObj.d_color === C_FLG_ON) {
7222
+ const tmpArrayData = splitLF(dosColorData);
7181
7223
 
7182
7224
  tmpArrayData.filter(data => hasVal(data)).forEach(tmpData => {
7183
7225
  const tmpColorData = tmpData.split(`,`);
@@ -7206,7 +7248,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7206
7248
  * @param {number} _scoreNo
7207
7249
  */
7208
7250
  const setCssMotionData = (_header, _scoreNo) => {
7209
- const dosCssMotionData = _dosObj[`${_header}Motion${_scoreNo}_data`] || _dosObj[`${_header}Motion_data`];
7251
+ const dosCssMotionData = getRefData(`${_header}Motion`, `${_scoreNo}_data`) || _dosObj[`${_header}Motion_data`];
7210
7252
  const cssMotionData = [];
7211
7253
 
7212
7254
  if (hasVal(dosCssMotionData) && g_stateObj.d_arroweffect === C_FLG_ON) {
@@ -7232,7 +7274,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7232
7274
  * @param {number} _scoreNo
7233
7275
  */
7234
7276
  const setScrollchData = (_scoreNo) => {
7235
- const dosScrollchData = _dosObj[`scrollch${_scoreNo}_data`] || _dosObj.scrollch_data;
7277
+ const dosScrollchData = getRefData(`scrollch`, `${_scoreNo}_data`) || _dosObj.scrollch_data;
7236
7278
  const scrollchData = [];
7237
7279
 
7238
7280
  if (hasVal(dosScrollchData)) {
@@ -7252,6 +7294,18 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7252
7294
  return [];
7253
7295
  };
7254
7296
 
7297
+ /**
7298
+ * 譜面データに別の関連名が含まれていた場合、関連名の変数を返す
7299
+ * 例) |backA2_data=back_data| -> back_dataで定義された値を使用
7300
+ * @param {string} _header
7301
+ * @param {string} _dataName
7302
+ * @returns
7303
+ */
7304
+ const getRefData = (_header, _dataName) => {
7305
+ const data = _dosObj[`${_header}${_dataName}`];
7306
+ return data?.startsWith(_header) ? _dosObj[data] : data;
7307
+ }
7308
+
7255
7309
  /**
7256
7310
  * 譜面データの優先順配列の取得
7257
7311
  * @param {string} _header
@@ -7260,10 +7314,10 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7260
7314
  * @returns
7261
7315
  */
7262
7316
  const getPriorityList = (_header, _type, _scoreNo) => [
7263
- _dosObj[`${_header}${_type}${g_localeObj.val}${_scoreNo}_data`],
7264
- _dosObj[`${_header}${_type}${g_localeObj.val}_data`],
7265
- _dosObj[`${_header}${_type}${_scoreNo}_data`],
7266
- _dosObj[`${_header}${_type}_data`]
7317
+ getRefData(_header, `${_type}${g_localeObj.val}${_scoreNo}_data`),
7318
+ getRefData(_header, `${_type}${g_localeObj.val}_data`),
7319
+ getRefData(_header, `${_type}${_scoreNo}_data`),
7320
+ getRefData(_header, `${_type}_data`)
7267
7321
  ];
7268
7322
 
7269
7323
  /**
@@ -7392,16 +7446,17 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7392
7446
 
7393
7447
  /**
7394
7448
  * リザルトモーションデータ(結果画面用背景・マスクデータ)の分解
7395
- * @param {string} _header
7396
- * @param {string} _scoreNo
7397
- * @param {string} _defaultHeader
7449
+ * @param {string} _header 背景、マスク (back, mask)
7450
+ * @param {string} _resultType リザルトモーションの種類 (result, failedB, failedS)
7451
+ * @param {string} _scoreNo 譜面番号
7452
+ * @param {string} _defaultType _resultTypeが無いときの代替名
7398
7453
  */
7399
- const makeBackgroundResultData = (_header, _scoreNo, _defaultHeader = ``) => {
7454
+ const makeBackgroundResultData = (_header, _resultType, _scoreNo, _defaultType = ``) => {
7400
7455
  const dataList = [];
7401
- const addResultDataList = _headerType => dataList.push(...getPriorityList(``, _headerType, _scoreNo));
7402
- addResultDataList(_header);
7403
- if (_defaultHeader !== ``) {
7404
- addResultDataList(_defaultHeader);
7456
+ const addDataList = (_type = ``) => dataList.push(...getPriorityList(_header, _type, _scoreNo));
7457
+ addDataList(_resultType);
7458
+ if (_defaultType !== ``) {
7459
+ addDataList(_defaultType);
7405
7460
  }
7406
7461
 
7407
7462
  const data = dataList.find((v) => v !== undefined);
@@ -7479,17 +7534,17 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7479
7534
  } else {
7480
7535
  g_animationData.forEach(sprite => {
7481
7536
  [g_headerObj[`${sprite}ResultData`], g_headerObj[`${sprite}ResultMaxDepth`]] =
7482
- makeBackgroundResultData(`${sprite}result`, scoreIdHeader);
7537
+ makeBackgroundResultData(sprite, `result`, scoreIdHeader);
7483
7538
  [g_headerObj[`${sprite}FailedData`], g_headerObj[`${sprite}FailedMaxDepth`]] =
7484
- makeBackgroundResultData(`${sprite}failed${g_stateObj.lifeMode.slice(0, 1)}`, scoreIdHeader, `${sprite}result`);
7539
+ makeBackgroundResultData(sprite, `failed${g_stateObj.lifeMode.slice(0, 1)}`, scoreIdHeader, `result`);
7485
7540
  });
7486
7541
  }
7487
7542
 
7488
7543
  // キー変化定義
7489
7544
  obj.keychFrames = [0];
7490
7545
  obj.keychTarget = [`0`];
7491
- if (hasVal(_dosObj[`keych${setScoreIdHeader(g_stateObj.scoreId, g_stateObj.scoreLockFlg)}_data`])) {
7492
- const keychdata = splitLF2(_dosObj[`keych${setScoreIdHeader(g_stateObj.scoreId, g_stateObj.scoreLockFlg)}_data`], `,`);
7546
+ if (hasVal(getRefData(`keych`, `${scoreIdHeader}_data`))) {
7547
+ const keychdata = splitLF2(getRefData(`keych`, `${scoreIdHeader}_data`), `,`);
7493
7548
  obj.keychFrames.push(...keychdata.filter((val, j) => j % 2 === 0));
7494
7549
  obj.keychTarget.push(...keychdata.filter((val, j) => j % 2 === 1));
7495
7550
  }
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2023/03/20 (v31.0.0)
8
+ * Revised : 2023/03/25 (v31.1.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -561,6 +561,9 @@ const g_settingBtnObj = {
561
561
  const g_limitObj = {
562
562
  adjustment: 30,
563
563
  hitPosition: 50,
564
+
565
+ densityDivision: 16,
566
+ densityMaxVals: 3,
564
567
  };
565
568
  const C_MAX_ADJUSTMENT = 30;
566
569
  const C_MAX_SPEED = 10;
@@ -2737,10 +2740,11 @@ const g_lang_msgObj = {
2737
2740
  hitPosition: `判定位置にズレを感じる場合、\n数値を変えることで判定の中央位置を1px単位(プラス:手前, マイナス:奥側)で調整することができます。\n早押し・遅押し傾向にある場合に使用します。`,
2738
2741
 
2739
2742
  configType: `キーコンフィグ対象を切り替えます。\n[Main] メインキーのみ, [Replaced] 代替キーのみ, [ALL] 全て`,
2740
- colorType: `矢印色の配色パターンを変更します。\nType1~4選択時は色変化が自動でOFFになります。\n[Type0] グラデーション切替, [Type1~4] デフォルトパターン`,
2743
+ colorType: `矢印・フリーズアローの配色セットをあらかじめ定義されたリストから選択できます。\nType1~4選択時は色変化が自動でOFFになり、カラーピッカーから好きな色に変更できます。\n[Type0] グラデーション切替, [Type1~4] デフォルトパターン`,
2741
2744
  imgType: `矢印・フリーズアローなどのオブジェクトの見た目を変更します。`,
2742
2745
  colorGroup: `矢印・フリーズアロー色グループの割り当てパターンを変更します。`,
2743
2746
  shuffleGroup: `Mirror/Asym-Mirror/Random/S-Random選択時、シャッフルするグループを変更します。\n矢印の上にある同じ数字同士でシャッフルします。`,
2747
+ stepRtnGroup: `矢印などノーツの種類、回転に関するパターンを切り替えます。\nあらかじめ設定されている場合のみ変更可能です。`,
2744
2748
 
2745
2749
  pickArrow: `色番号ごとの矢印色(枠、塗りつぶし)、通常時のフリーズアロー色(枠、帯)を\nカラーピッカーから選んで変更できます。`,
2746
2750
  pickColorCopy: `このボタンを押すと、フリーズアローの配色を矢印(枠)の色で上書きします。\nヒット時のフリーズアローの色も上書きします。`,
@@ -2792,10 +2796,11 @@ const g_lang_msgObj = {
2792
2796
  hitPosition: `If you feel a discrepancy in the judgment position, \nyou can adjust the center position of the judgment in 1px increments \n (plus: in front, minus: at the back) by changing the numerical value. \nUse this function when there is a tendency to push too fast or too slow.`,
2793
2797
 
2794
2798
  configType: `Switch the key config target.\n[Main] main keys only, [Replaced] alternate keys only, [ALL] all keys`,
2795
- colorType: `Change the color scheme of the sequences color.\nWhen Type 1 to 4 are selected, the color change is automatically turned off.\n[Type0] Switch the sequences color gradations, [Type1~4] default color scheme`,
2799
+ colorType: `Change the color scheme set for arrows and freeze-arrows from the predefined set.\nWhen Type1 to 4 is selected, color change is automatically turned off and can be changed to any color from the color picker.\n[Type0] Switch the sequences color gradations, [Type1~4] default color scheme`,
2796
2800
  imgType: `Change the appearance of sequences.`,
2797
2801
  colorGroup: `Change the sequences color group assignment pattern.`,
2798
2802
  shuffleGroup: `Change the shuffle group when Mirror, Asym-Mirror, Random or S-Random are selected.\nShuffle with the same numbers listed above.`,
2803
+ stepRtnGroup: `Switches the type of notes, such as arrows, and the pattern regarding rotation.\nThis can only be changed if it has been set in advance.`,
2799
2804
 
2800
2805
  pickArrow: `Change the frame or fill of arrow color and the frame or bar of normal freeze-arrow color\nfor each color number from the color picker.`,
2801
2806
  pickColorCopy: `Pressing this button will override the color scheme of the freeze arrow with the frame color of the arrow. \nIt also overrides the color of the freeze arrow on hit.`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "31.0.1",
3
+ "version": "31.2.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "index.js",
6
6
  "scripts": {