danoniplus 32.5.0 → 32.6.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/06/24
7
+ * Revised : 2023/07/08
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 32.5.0`;
12
- const g_revisedDate = `2023/06/24`;
11
+ const g_version = `Ver 32.6.1`;
12
+ const g_revisedDate = `2023/07/08`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -170,7 +170,7 @@ const g_wordObj = {
170
170
  fadeInFlg0: false,
171
171
  fadeInFlg1: false,
172
172
  fadeOutFlg0: false,
173
- fadeOutFlg1: false
173
+ fadeOutFlg1: false,
174
174
  };
175
175
 
176
176
  // オーディオ設定・タイマー管理
@@ -253,6 +253,31 @@ const convertStrToVal = _str => {
253
253
  */
254
254
  const hasVal = _data => _data !== undefined && _data !== ``;
255
255
 
256
+ /**
257
+ * 変数が存在するかどうかをチェック(null無しを含む)
258
+ * @param {string} _data
259
+ */
260
+ const hasValN = _data => hasVal(_data) && _data !== null;
261
+
262
+ /**
263
+ * 文字列から他の型へ変換する処理群
264
+ */
265
+ const g_convFunc = {
266
+ float: (_checkStr, _default) => isNaN(parseFloat(_checkStr)) ? _default : parseFloat(_checkStr),
267
+ number: (_checkStr, _default) => isNaN(parseInt(_checkStr)) ? _default : parseInt(_checkStr),
268
+ boolean: (_checkStr, _default) => _checkStr.toString().toLowerCase() === `true` ? true :
269
+ (_checkStr.toString().toLowerCase() === `false` ? false : _default),
270
+ switch: (_checkStr, _default) => [C_FLG_OFF, C_FLG_ON].includes(_checkStr.toString().toUpperCase()) ? _checkStr.toString().toUpperCase() : _default,
271
+ calc: (_checkStr, _default) => {
272
+ try {
273
+ return new Function(`return ${_checkStr}`)();
274
+ } catch (err) {
275
+ return _default;
276
+ }
277
+ },
278
+ string: (_checkStr) => _checkStr,
279
+ };
280
+
256
281
  /**
257
282
  * 文字列を想定された型に変換
258
283
  * - _type は `float`(小数)、`number`(整数)、`boolean`(真偽値)、
@@ -262,62 +287,22 @@ const hasVal = _data => _data !== undefined && _data !== ``;
262
287
  * @param {string} _default
263
288
  * @param {string} _type
264
289
  */
265
- const setVal = (_checkStr, _default, _type = C_TYP_STRING) => {
266
-
267
- let convertStr = _checkStr;
268
-
269
- // 値がundefined相当の場合は無条件でデフォルト値を返却
270
- if (_checkStr === undefined || _checkStr === null || _checkStr === ``) {
271
- return _default;
272
- }
273
-
274
- if (_type === C_TYP_FLOAT) {
275
- // 数値型(小数可)の場合
276
- const toFloat = parseFloat(_checkStr);
277
- convertStr = (isNaN(toFloat) ? _default : toFloat);
278
-
279
- } else if (_type === C_TYP_NUMBER) {
280
- // 数値型(整数のみ)の場合
281
- const toInt = parseInt(_checkStr);
282
- convertStr = (isNaN(toInt) ? _default : toInt);
283
-
284
- } else if (_type === C_TYP_BOOLEAN) {
285
- // 真偽値の場合
286
- const lowerCase = _checkStr.toString().toLowerCase();
287
- convertStr = (lowerCase === `true` ? true : (lowerCase === `false` ? false : _default));
288
-
289
- } else if (_type === C_TYP_SWITCH) {
290
- // ON/OFFスイッチの場合
291
- const toSwtich = _checkStr.toString().toUpperCase();
292
- convertStr = [C_FLG_OFF, C_FLG_ON].includes(toSwtich) ? toSwtich : _default;
293
-
294
- } else if (_type === C_TYP_CALC) {
295
- try {
296
- convertStr = new Function(`return ${_checkStr}`)();
297
- } catch (err) {
298
- convertStr = _default;
299
- }
300
- }
301
-
302
- // 文字列型の場合 (最初でチェック済みのためそのまま値を返却)
303
- return convertStr;
304
- };
290
+ const setVal = (_checkStr, _default, _type = C_TYP_STRING) =>
291
+ hasValN(_checkStr) ? g_convFunc[_type](_checkStr, _default) : _default;
305
292
 
306
293
  /**
307
294
  * ブール値への変換
308
295
  * @param {string} _val
309
- * @param {boolean} _defaultVal
310
- * @returns
296
+ * @param {boolean} _defaultVal
311
297
  */
312
- const setBoolVal = (_val, _defaultVal = false) => setVal(_val, _defaultVal, C_TYP_BOOLEAN);
298
+ const setBoolVal = (_val, _defaultVal = false) => hasValN(_val) ? g_convFunc.boolean(_val, _defaultVal) : _defaultVal;
313
299
 
314
300
  /**
315
301
  * 整数値への変換
316
302
  * @param {string} _val
317
- * @param {number} _defaultVal
318
- * @returns
303
+ * @param {number} _defaultVal
319
304
  */
320
- const setIntVal = (_val, _defaultVal = 0) => setVal(_val, _defaultVal, C_TYP_NUMBER);
305
+ const setIntVal = (_val, _defaultVal = 0) => hasValN(_val) ? g_convFunc.number(_val, _defaultVal) : _defaultVal;
321
306
 
322
307
  /**
323
308
  * 先頭のみ大文字に変換(それ以降はそのまま)
@@ -335,12 +320,19 @@ const toCapitalize = _str => {
335
320
  */
336
321
  const roundZero = (_num, _init = 0) => _num < 0 ? _init : _num;
337
322
 
323
+ /**
324
+ * 配列から_targetに合致する配列位置を返す
325
+ * 存在しない場合は0を返却
326
+ * @param {array} _list
327
+ * @param {string} _target
328
+ */
329
+ const getCurrentNo = (_list, _target) => roundZero(_list.indexOf(_target));
330
+
338
331
  /**
339
332
  * 配列内に存在するかどうかをチェック
340
333
  * @param {string} _val
341
334
  * @param {array} _array
342
- * @param {integer} _pos
343
- * @returns
335
+ * @param {integer} _pos
344
336
  */
345
337
  const hasValInArray = (_val, _array, _pos = 0) =>
346
338
  _array.findIndex(data => data[_pos] === _val) !== -1;
@@ -348,15 +340,13 @@ const hasValInArray = (_val, _array, _pos = 0) =>
348
340
  /**
349
341
  * 配列が既定長以上かどうかをチェック
350
342
  * @param {array} _data
351
- * @param {integer} _length
352
- * @returns
343
+ * @param {integer} _length
353
344
  */
354
345
  const hasArrayList = (_data, _length = 1) => _data !== undefined && _data.length >= _length;
355
346
 
356
347
  /**
357
348
  * 改行コード区切りの配列展開
358
- * @param {string} _str
359
- * @returns
349
+ * @param {string} _str
360
350
  */
361
351
  const splitLF = _str => _str.split(`\r`).join(`\n`).split(`\n`);
362
352
 
@@ -364,31 +354,27 @@ const splitLF = _str => _str.split(`\r`).join(`\n`).split(`\n`);
364
354
  * 改行コード区切りを本来の区切り文字に変換して配列展開
365
355
  * (改行区切りで間が空行だった場合は無効化)
366
356
  * @param {string} _str
367
- * @param {string} _delim
368
- * @returns
357
+ * @param {string} _delim
369
358
  */
370
359
  const splitLF2 = (_str, _delim = `$`) => splitLF(_str).filter(val => val !== ``).join(_delim).split(_delim);
371
360
 
372
361
  /**
373
362
  * 重複を排除した配列の生成
374
363
  * @param {array} _array1
375
- * @param {...any} _arrays
376
- * @returns
364
+ * @param {...any} _arrays
377
365
  */
378
366
  const makeDedupliArray = (_array1, ..._arrays) =>
379
367
  Array.from((new Set([..._array1, ..._arrays.flat()])).values()).filter(val => val !== undefined);
380
368
 
381
369
  /**
382
370
  * 二次元配列のコピー
383
- * @param {array2} _array2d
384
- * @returns
371
+ * @param {array2} _array2d
385
372
  */
386
373
  const copyArray2d = _array2d => structuredClone(_array2d);
387
374
 
388
375
  /**
389
376
  * 配列データを合計
390
- * @param {array} _array
391
- * @returns
377
+ * @param {array} _array
392
378
  */
393
379
  const sumData = _array => _array.reduce((p, x) => p + x);
394
380
 
@@ -396,8 +382,7 @@ const sumData = _array => _array.reduce((p, x) => p + x);
396
382
  * 最小配列長の配列を作成
397
383
  * @param {array} _array
398
384
  * @param {number} _minLength
399
- * @param {number} _defaultVal
400
- * @returns
385
+ * @param {number} _defaultVal
401
386
  */
402
387
  const makeBaseArray = (_array = [], _minLength, _defaultVal) => padArray(_array, [...Array(_minLength)].fill(_defaultVal));
403
388
 
@@ -405,7 +390,6 @@ const makeBaseArray = (_array = [], _minLength, _defaultVal) => padArray(_array,
405
390
  * ベースとする配列に対して別の配列で上書き
406
391
  * @param {array} _array
407
392
  * @param {array} _baseArray ベースとする配列
408
- * @returns
409
393
  */
410
394
  const padArray = (_array, _baseArray) => {
411
395
  _array?.forEach((val, j) => {
@@ -423,8 +407,7 @@ const padArray = (_array, _baseArray) => {
423
407
  * [1, 3, 2, 4, 6, 4, 5] -> [[4], [6], [3, 5]]
424
408
  * [9, 6, 9, 9, 8, 7, 5] -> [[0, 2, 3]]
425
409
  * @param {array} _array
426
- * @param {number} _num
427
- * @returns
410
+ * @param {number} _num
428
411
  */
429
412
  const getMaxValIdxs = (_array, _num = 1) => {
430
413
  const getMaxVal = (_a, _b) => Math.max(_a, _b);
@@ -469,9 +452,7 @@ const fuzzyListMatching = (_str, _headerList, _footerList) =>
469
452
  */
470
453
  const replaceStr = (_str, _pairs) => {
471
454
  let tmpStr = _str;
472
- _pairs.forEach(pair => {
473
- tmpStr = tmpStr.replaceAll(pair[0], pair[1]);
474
- });
455
+ _pairs.forEach(pair => tmpStr = tmpStr.replaceAll(pair[0], pair[1]));
475
456
  return tmpStr;
476
457
  };
477
458
 
@@ -504,8 +485,7 @@ const escapeHtmlForArray = _array => _array.map(str => escapeHtml(str));
504
485
  * 次のカーソルへ移動
505
486
  * @param {number} _basePos
506
487
  * @param {number} _num
507
- * @param {number} _length
508
- * @returns
488
+ * @param {number} _length
509
489
  */
510
490
  const nextPos = (_basePos, _num, _length) => (_basePos + _length + _num) % _length;
511
491
 
@@ -607,7 +587,7 @@ const createScText = (_obj, _settingLabel, { displayName = `option`, dfLabel = `
607
587
  * 各画面の汎用ショートカットキー表示
608
588
  * @param {string} _displayName
609
589
  */
610
- const createScTextCommon = _displayName => {
590
+ const createScTextCommon = _displayName =>
611
591
  Object.keys(g_btnPatterns[_displayName]).filter(target => document.getElementById(`btn${target}`) !== null)
612
592
  .forEach(target =>
613
593
  createScText(document.getElementById(`btn${target}`), target, {
@@ -615,7 +595,6 @@ const createScTextCommon = _displayName => {
615
595
  dfLabel: g_lblNameObj[`sc_${_displayName}${target}`] ?? ``,
616
596
  x: g_btnPatterns[_displayName][target],
617
597
  }));
618
- };
619
598
 
620
599
  /**
621
600
  * ショートカットキー有効化
@@ -658,8 +637,7 @@ const openLink = _url => {
658
637
 
659
638
  /**
660
639
  * URLのフルパスを取得
661
- * @param {string} _url
662
- * @returns
640
+ * @param {string} _url
663
641
  */
664
642
  const getFullPath = _url => {
665
643
  const link = document.createElement(`a`);
@@ -823,8 +801,7 @@ const getFilePath = (_fileName, _directory = ``) => {
823
801
 
824
802
  /**
825
803
  * 対象のカラーコードが明暗どちらかを判定 (true: 明色, false: 暗色)
826
- * @param {string} _colorStr
827
- * @returns
804
+ * @param {string} _colorStr
828
805
  */
829
806
  const checkLightOrDark = _colorStr => {
830
807
  const r = parseInt(_colorStr.substring(1, 3), 16);
@@ -851,15 +828,13 @@ const byteToHex = _num => (`${_num.toString(16).padStart(2, '0')}`);
851
828
 
852
829
  /**
853
830
  * カラーコードかどうかを判定 (簡易版)
854
- * @param {string} _str
855
- * @returns
831
+ * @param {string} _str
856
832
  */
857
833
  const isColorCd = _str => _str.substring(0, 1) === `#`;
858
834
 
859
835
  /**
860
836
  * CSSの位置表記系かどうかをチェック
861
- * @param {string} _str
862
- * @returns
837
+ * @param {string} _str
863
838
  */
864
839
  const hasAnglePointInfo = _str => fuzzyListMatching(_str, g_checkStr.cssHeader, g_checkStr.cssFooter);
865
840
 
@@ -990,7 +965,6 @@ const getFontSize = (_str, _maxWidth, _font = getBasicFont(), _maxFontsize = 64,
990
965
  * @param {string} _id
991
966
  * @param {string} _str
992
967
  * @param {string} _altId
993
- * @returns
994
968
  */
995
969
  const createDescDiv = (_id, _str, _altId = _id) =>
996
970
  createDivCss2Label(_id, _str, Object.assign(g_lblPosObj[_altId], {
@@ -1081,8 +1055,7 @@ const createImg = (_id, _imgPath, _x, _y, _width, _height) => {
1081
1055
  * @param {string} _parentObj
1082
1056
  * @param {string} _id
1083
1057
  * @param {function} _func
1084
- * @param {object} _obj
1085
- * @returns
1058
+ * @param {object} _obj
1086
1059
  */
1087
1060
  const createColorPicker = (_parentObj, _id, _func, { x = 0, y = 0 } = {}) => {
1088
1061
  const picker = document.createElement(`input`);
@@ -1137,8 +1110,7 @@ const createColorObject2 = (_id,
1137
1110
  * @param {object} _parentObj 親スプライト
1138
1111
  * @param {string} _newObjId 作成する子スプライト名
1139
1112
  * @param {object} _obj (x, y, w, h, ...rest)
1140
- * @param {...any} _classes
1141
- * @returns
1113
+ * @param {...any} _classes
1142
1114
  */
1143
1115
  const createEmptySprite = (_parentObj, _newObjId, { x = 0, y = 0, w = g_sWidth, h = g_sHeight, title = ``, ...rest } = {}, ..._classes) => {
1144
1116
  if (document.getElementById(_newObjId) !== null) {
@@ -1508,83 +1480,84 @@ const makeSpriteData = (_data, _calcFrame = _frame => _frame) => {
1508
1480
  const tmpSpriteData = tmpData.split(`,`);
1509
1481
 
1510
1482
  // 深度が"-"の場合はスキップ
1511
- if (tmpSpriteData.length > 1 && tmpSpriteData[1] !== `-`) {
1483
+ if (tmpSpriteData.length <= 1 || tmpSpriteData[1] === `-`) {
1484
+ return;
1485
+ }
1512
1486
 
1513
- // 値チェックとエスケープ処理
1514
- let tmpFrame;
1515
- if (setIntVal(tmpSpriteData[0], -1) === 0) {
1516
- tmpFrame = 0;
1517
- } else {
1518
- tmpFrame = roundZero(_calcFrame(setVal(tmpSpriteData[0], 200, C_TYP_CALC)));
1519
- }
1520
- const tmpDepth = (tmpSpriteData[1] === C_FLG_ALL ? C_FLG_ALL : setVal(tmpSpriteData[1], 0, C_TYP_CALC));
1521
- if (tmpDepth !== C_FLG_ALL && tmpDepth > maxDepth) {
1522
- maxDepth = tmpDepth;
1523
- }
1524
-
1525
- const tmpObj = {
1526
- path: escapeHtml(tmpSpriteData[2] ?? ``, g_escapeStr.escapeCode), // 画像パス or テキスト
1527
- class: escapeHtml(tmpSpriteData[3] ?? ``), // CSSクラス
1528
- left: setVal(tmpSpriteData[4], `0`).includes(`{`) ?
1529
- `${setVal(tmpSpriteData[4], 0)}` : `{${setVal(tmpSpriteData[4], 0)}}`, // X座標
1530
- top: setVal(tmpSpriteData[5], `0`).includes(`{`) ?
1531
- `${setVal(tmpSpriteData[5], 0)}` : `{${setVal(tmpSpriteData[5], 0)}}`, // Y座標
1532
- width: `${setIntVal(tmpSpriteData[6])}`, // spanタグの場合は font-size
1533
- height: `${escapeHtml(tmpSpriteData[7] ?? ``)}`, // spanタグの場合は color(文字列可)
1534
- opacity: setVal(tmpSpriteData[8], 1, C_TYP_FLOAT),
1535
- animationName: escapeHtml(setVal(tmpSpriteData[9], C_DIS_NONE)),
1536
- animationDuration: setIntVal(tmpSpriteData[10]) / g_fps,
1537
- };
1538
- if (setVal(tmpSpriteData[11], g_presetObj.animationFillMode) !== undefined) {
1539
- tmpObj.animationFillMode = setVal(tmpSpriteData[11], g_presetObj.animationFillMode);
1540
- }
1541
- if (g_headerObj.autoPreload) {
1542
- if (checkImage(tmpObj.path)) {
1543
- if (g_headerObj.syncBackPath) {
1544
- const [file, dir] = getFilePath(tmpObj.path, `./`);
1545
- tmpObj.path = `${dir}${file}`;
1546
- }
1547
- preloadFile(`image`, tmpObj.path);
1487
+ // 値チェックとエスケープ処理
1488
+ let tmpFrame;
1489
+ if (setIntVal(tmpSpriteData[0], -1) === 0) {
1490
+ tmpFrame = 0;
1491
+ } else {
1492
+ tmpFrame = roundZero(_calcFrame(setVal(tmpSpriteData[0], 200, C_TYP_CALC)));
1493
+ }
1494
+ const tmpDepth = (tmpSpriteData[1] === C_FLG_ALL ? C_FLG_ALL : setVal(tmpSpriteData[1], 0, C_TYP_CALC));
1495
+ if (tmpDepth !== C_FLG_ALL && tmpDepth > maxDepth) {
1496
+ maxDepth = tmpDepth;
1497
+ }
1498
+
1499
+ const tmpObj = {
1500
+ path: escapeHtml(tmpSpriteData[2] ?? ``, g_escapeStr.escapeCode), // 画像パス or テキスト
1501
+ class: escapeHtml(tmpSpriteData[3] ?? ``), // CSSクラス
1502
+ left: setVal(tmpSpriteData[4], `0`).includes(`{`) ?
1503
+ `${setVal(tmpSpriteData[4], 0)}` : `{${setVal(tmpSpriteData[4], 0)}}`, // X座標
1504
+ top: setVal(tmpSpriteData[5], `0`).includes(`{`) ?
1505
+ `${setVal(tmpSpriteData[5], 0)}` : `{${setVal(tmpSpriteData[5], 0)}}`, // Y座標
1506
+ width: `${setIntVal(tmpSpriteData[6])}`, // spanタグの場合は font-size
1507
+ height: `${escapeHtml(tmpSpriteData[7] ?? ``)}`, // spanタグの場合は color(文字列可)
1508
+ opacity: setVal(tmpSpriteData[8], 1, C_TYP_FLOAT),
1509
+ animationName: escapeHtml(setVal(tmpSpriteData[9], C_DIS_NONE)),
1510
+ animationDuration: setIntVal(tmpSpriteData[10]) / g_fps,
1511
+ };
1512
+ if (setVal(tmpSpriteData[11], g_presetObj.animationFillMode) !== undefined) {
1513
+ tmpObj.animationFillMode = setVal(tmpSpriteData[11], g_presetObj.animationFillMode);
1514
+ }
1515
+ if (g_headerObj.autoPreload) {
1516
+ if (checkImage(tmpObj.path)) {
1517
+ if (g_headerObj.syncBackPath) {
1518
+ const [file, dir] = getFilePath(tmpObj.path, `./`);
1519
+ tmpObj.path = `${dir}${file}`;
1548
1520
  }
1521
+ preloadFile(`image`, tmpObj.path);
1549
1522
  }
1523
+ }
1550
1524
 
1551
- let addFrame = 0;
1552
- [spriteData[tmpFrame], addFrame] =
1553
- checkDuplicatedObjects(spriteData[tmpFrame]);
1554
-
1555
- const emptyPatterns = [``, `[loop]`, `[jump]`];
1556
- const colorObjFlg = tmpSpriteData[2]?.startsWith(`[c]`) || false;
1557
- spriteData[tmpFrame][addFrame] = {
1558
- depth: tmpDepth,
1559
- };
1525
+ let addFrame = 0;
1526
+ [spriteData[tmpFrame], addFrame] =
1527
+ checkDuplicatedObjects(spriteData[tmpFrame]);
1560
1528
 
1561
- if (colorObjFlg) {
1562
- // [c]始まりの場合、カラーオブジェクト用の作成準備を行う
1563
- const data = tmpObj.path.slice(`[c]`.length).split(`/`);
1564
- spriteData[tmpFrame][addFrame].colorObjInfo = {
1565
- x: tmpObj.left, y: tmpObj.top, w: tmpObj.width, h: tmpObj.height,
1566
- rotate: setVal(data[0], `0`), opacity: tmpObj.opacity,
1567
- background: makeColorGradation(setVal(data[1], `#ffffff`), { _defaultColorgrd: false }),
1568
- animationName: tmpObj.animationName,
1569
- animationDuration: `${tmpObj.animationDuration}s`,
1570
- };
1571
- spriteData[tmpFrame][addFrame].colorObjId = `${tmpFrame}_${addFrame}`;
1572
- spriteData[tmpFrame][addFrame].colorObjClass = setVal(tmpObj.class, undefined);
1573
- if (tmpObj.animationFillMode !== undefined) {
1574
- spriteData[tmpFrame][addFrame].colorObjInfo.animationFillMode = tmpObj.animationFillMode;
1575
- }
1529
+ const emptyPatterns = [``, `[loop]`, `[jump]`];
1530
+ const colorObjFlg = tmpSpriteData[2]?.startsWith(`[c]`) || false;
1531
+ const spriteFrameData = spriteData[tmpFrame][addFrame] = {
1532
+ depth: tmpDepth,
1533
+ };
1576
1534
 
1577
- } else if (emptyPatterns.includes(tmpObj.path)) {
1578
- // ループ、フレームジャンプ、空の場合の処理
1579
- spriteData[tmpFrame][addFrame].command = tmpObj.path;
1580
- spriteData[tmpFrame][addFrame].jumpFrame = tmpObj.class;
1581
- spriteData[tmpFrame][addFrame].maxLoop = tmpObj.left;
1582
- spriteData[tmpFrame][addFrame].htmlText = ``;
1583
- } else {
1584
- // それ以外の画像、テキストの場合
1585
- spriteData[tmpFrame][addFrame].animationName = tmpObj.animationName;
1586
- spriteData[tmpFrame][addFrame].htmlText = (checkImage(tmpObj.path) ? makeSpriteImage(tmpObj) : makeSpriteText(tmpObj));
1587
- }
1535
+ if (colorObjFlg) {
1536
+ // [c]始まりの場合、カラーオブジェクト用の作成準備を行う
1537
+ const data = tmpObj.path.slice(`[c]`.length).split(`/`);
1538
+ spriteFrameData.colorObjInfo = {
1539
+ x: tmpObj.left, y: tmpObj.top, w: tmpObj.width, h: tmpObj.height,
1540
+ rotate: setVal(data[0], `0`), opacity: tmpObj.opacity,
1541
+ background: makeColorGradation(setVal(data[1], `#ffffff`), { _defaultColorgrd: false }),
1542
+ animationName: tmpObj.animationName,
1543
+ animationDuration: `${tmpObj.animationDuration}s`,
1544
+ };
1545
+ spriteFrameData.colorObjId = `${tmpFrame}_${addFrame}`;
1546
+ spriteFrameData.colorObjClass = setVal(tmpObj.class, undefined);
1547
+ if (tmpObj.animationFillMode !== undefined) {
1548
+ spriteFrameData.colorObjInfo.animationFillMode = tmpObj.animationFillMode;
1549
+ }
1550
+
1551
+ } else if (emptyPatterns.includes(tmpObj.path)) {
1552
+ // ループ、フレームジャンプ、空の場合の処理
1553
+ spriteFrameData.command = tmpObj.path;
1554
+ spriteFrameData.jumpFrame = tmpObj.class;
1555
+ spriteFrameData.maxLoop = tmpObj.left;
1556
+ spriteFrameData.htmlText = ``;
1557
+ } else {
1558
+ // それ以外の画像、テキストの場合
1559
+ spriteFrameData.animationName = tmpObj.animationName;
1560
+ spriteFrameData.htmlText = (checkImage(tmpObj.path) ? makeSpriteImage(tmpObj) : makeSpriteText(tmpObj));
1588
1561
  }
1589
1562
  });
1590
1563
 
@@ -1714,10 +1687,7 @@ class AudioPlayer {
1714
1687
  this._duration = _buffer.duration;
1715
1688
  this._buffer = _buffer;
1716
1689
  });
1717
-
1718
- if (this._eventListeners[`canplaythrough`] !== undefined) {
1719
- this._eventListeners[`canplaythrough`].forEach(_listener => _listener());
1720
- }
1690
+ this._eventListeners[`canplaythrough`]?.forEach(_listener => _listener());
1721
1691
  }
1722
1692
 
1723
1693
  play(_adjustmentTime = 0) {
@@ -2199,8 +2169,7 @@ const resetColorAndGauge = _scoreId => {
2199
2169
  /**
2200
2170
  * 譜面番号固定かつ譜面ファイル分割時に初期色情報を他譜面へコピー
2201
2171
  * @param {object} _baseObj
2202
- * @param {number} _scoreId
2203
- * @returns
2172
+ * @param {number} _scoreId
2204
2173
  */
2205
2174
  const copySetColor = (_baseObj, _scoreId) => {
2206
2175
  const obj = {};
@@ -2217,8 +2186,7 @@ const copySetColor = (_baseObj, _scoreId) => {
2217
2186
 
2218
2187
  /**
2219
2188
  * MusicUrlの基本情報を取得
2220
- * @param {number} _scoreId
2221
- * @returns
2189
+ * @param {number} _scoreId
2222
2190
  */
2223
2191
  const getMusicUrl = _scoreId => {
2224
2192
  return g_headerObj.musicUrls !== undefined ?
@@ -2260,7 +2228,7 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2260
2228
  noteCnt.frz[j] = 0;
2261
2229
 
2262
2230
  const tmpFrzData = _scoreObj.frzData[j].filter((data, k) => k % 2 === 0);
2263
- [_scoreObj.arrowData[j], tmpFrzData].forEach((typeData, m) => {
2231
+ [_scoreObj.arrowData[j], tmpFrzData].forEach((typeData, m) =>
2264
2232
  typeData.forEach(note => {
2265
2233
  if (isNaN(parseFloat(note))) {
2266
2234
  return;
@@ -2271,8 +2239,7 @@ const storeBaseData = (_scoreId, _scoreObj, _keyCtrlPtn) => {
2271
2239
  noteCnt[types[m]][j]++;
2272
2240
  allData++;
2273
2241
  }
2274
- });
2275
- });
2242
+ }));
2276
2243
  fullData = fullData.concat(..._scoreObj.arrowData[j], ...tmpFrzData);
2277
2244
  }
2278
2245
 
@@ -2497,8 +2464,7 @@ const calcLevel = _scoreObj => {
2497
2464
 
2498
2465
  /**
2499
2466
  * 譜面ヘッダーの分解(スキン、jsファイルなどの設定)
2500
- * @param {object} _dosObj
2501
- * @returns
2467
+ * @param {object} _dosObj
2502
2468
  */
2503
2469
  const preheaderConvert = _dosObj => {
2504
2470
 
@@ -2514,14 +2480,13 @@ const preheaderConvert = _dosObj => {
2514
2480
  obj.jsData = [];
2515
2481
  obj.stepRtnUse = true;
2516
2482
 
2517
- const setJsFiles = (_files, _defaultDir, _type = `custom`) => {
2483
+ const setJsFiles = (_files, _defaultDir, _type = `custom`) =>
2518
2484
  _files.forEach(file => {
2519
2485
  if (hasVal(file)) {
2520
2486
  const [jsFile, jsDir] = getFilePath(file, _defaultDir);
2521
2487
  obj.jsData.push([_type === `skin` ? `danoni_skin_${jsFile}.js` : jsFile, jsDir]);
2522
2488
  }
2523
2489
  });
2524
- };
2525
2490
 
2526
2491
  // 外部スキンファイルの指定
2527
2492
  const tmpSkinType = _dosObj.skinType ?? g_presetObj.skinType ?? `default`;
@@ -2562,8 +2527,7 @@ const headerConvert = _dosObj => {
2562
2527
  /**
2563
2528
  * ロケールを含んだヘッダーの取得
2564
2529
  * @param {object} _obj
2565
- * @param {string} _param
2566
- * @returns
2530
+ * @param {string} _param
2567
2531
  */
2568
2532
  const getHeader = (_obj, _param) => _obj[`${_param}${g_localeObj.val}`] ?? _obj[_param];
2569
2533
 
@@ -2673,7 +2637,7 @@ const headerConvert = _dosObj => {
2673
2637
  obj.minSpeed = C_MIN_SPEED;
2674
2638
  obj.maxSpeed = C_MAX_SPEED;
2675
2639
  }
2676
- g_settings.speeds = [...Array((obj.maxSpeed - obj.minSpeed) * 20 + 1).keys()].map(i => obj.minSpeed + i / 20);
2640
+ g_settings.speeds = makeSpeedList(obj.minSpeed, obj.maxSpeed);
2677
2641
 
2678
2642
  // プレイ中のショートカットキー
2679
2643
  obj.keyRetry = setIntVal(getKeyCtrlVal(_dosObj.keyRetry), C_KEY_RETRY);
@@ -2993,14 +2957,12 @@ const headerConvert = _dosObj => {
2993
2957
  obj.titleAnimationDelay[j] = setVal(titleAnimation[2] / g_fps, obj.titleAnimationDelay[0], C_TYP_FLOAT);
2994
2958
  obj.titleAnimationTimingFunction[j] = setVal(titleAnimation[3], obj.titleAnimationName[3]);
2995
2959
  });
2996
- _dosObj.titleanimationclass?.split(`$`).forEach((animationClass, j) => {
2997
- obj.titleAnimationClass[j] = animationClass ?? ``;
2998
- });
2960
+ _dosObj.titleanimationclass?.split(`$`).forEach((animationClass, j) =>
2961
+ obj.titleAnimationClass[j] = animationClass ?? ``);
2999
2962
 
3000
2963
  if (obj.titleAnimationName.length === 1) {
3001
- g_titleLists.animation.forEach(pattern => {
3002
- obj[`titleAnimation${pattern}`][1] = obj[`titleAnimation${pattern}`][0];
3003
- });
2964
+ g_titleLists.animation.forEach(pattern =>
2965
+ obj[`titleAnimation${pattern}`][1] = obj[`titleAnimation${pattern}`][0]);
3004
2966
  }
3005
2967
  if (obj.titleAnimationClass.length === 1) {
3006
2968
  obj.titleAnimationClass[1] = obj.titleAnimationClass[0];
@@ -3027,9 +2989,8 @@ const headerConvert = _dosObj => {
3027
2989
  }
3028
2990
 
3029
2991
  // オプション利用可否設定
3030
- g_canDisabledSettings.forEach(option => {
3031
- obj[`${option}Use`] = setBoolVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true);
3032
- });
2992
+ g_canDisabledSettings.forEach(option =>
2993
+ obj[`${option}Use`] = setBoolVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true));
3033
2994
 
3034
2995
  let interlockingErrorFlg = false;
3035
2996
  g_displays.forEach((option, j) => {
@@ -3062,12 +3023,11 @@ const headerConvert = _dosObj => {
3062
3023
  });
3063
3024
 
3064
3025
  if (!interlockingErrorFlg) {
3065
- g_displays.forEach(option => {
3026
+ g_displays.forEach(option =>
3066
3027
  obj[`${option}ChainOFF`].forEach(defaultOption => {
3067
3028
  g_stateObj[`d_${defaultOption.toLowerCase()}`] = C_FLG_OFF;
3068
3029
  interlockingButton(obj, defaultOption, C_FLG_OFF, C_FLG_ON);
3069
- });
3070
- });
3030
+ }));
3071
3031
  }
3072
3032
 
3073
3033
  // ローカルストレージに保存済みのColorType設定からDisplayのColor設定を反映
@@ -3178,7 +3138,6 @@ const headerConvert = _dosObj => {
3178
3138
  * 譜面リスト作成有無の状態を取得
3179
3139
  * @param {boolean} _headerFlg
3180
3140
  * @param {array} _viewLists
3181
- * @returns
3182
3141
  */
3183
3142
  const getDifSelectorUse = (_headerFlg, _viewLists = g_headerObj.viewLists) => setBoolVal(_headerFlg, _viewLists.length > 5);
3184
3143
 
@@ -3197,7 +3156,6 @@ const resetColorType = ({ _from = ``, _to = ``, _fromObj = g_headerObj, _toObj =
3197
3156
  * 配列にデータを先頭に追加
3198
3157
  * @param {array} _arr
3199
3158
  * @param {string} _target
3200
- * @returns
3201
3159
  */
3202
3160
  const addValtoArray = (_arr, _target) => {
3203
3161
  if (!_arr.includes(_target)) {
@@ -3521,8 +3479,7 @@ const getGaugeSetting = (_dosObj, _name, _difLength, { scoreId = 0 } = {}) => {
3521
3479
 
3522
3480
  /**
3523
3481
  * キー名の取得
3524
- * @param {string} _key
3525
- * @returns
3482
+ * @param {string} _key
3526
3483
  */
3527
3484
  const getKeyName = _key => hasVal(g_keyObj[`keyName${_key}`]) ? g_keyObj[`keyName${_key}`] : _key;
3528
3485
 
@@ -3530,8 +3487,7 @@ const getKeyName = _key => hasVal(g_keyObj[`keyName${_key}`]) ? g_keyObj[`keyNam
3530
3487
  * KeyBoardEvent.code の値をCW Edition用のキーコードに変換
3531
3488
  * 簡略指定ができるように、以下の記述を許容
3532
3489
  * 例) KeyD -> D, ArrowDown -> Down, AltLeft -> Alt
3533
- * @param {string} _kCdN
3534
- * @returns
3490
+ * @param {string} _kCdN
3535
3491
  */
3536
3492
  const getKeyCtrlVal = _kCdN => {
3537
3493
  const convVal = Object.keys(g_kCdN).findIndex(val =>
@@ -3566,8 +3522,7 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
3566
3522
  * キーパターン(相対パターン)をキーパターン(実際のパターン番号)に変換
3567
3523
  * 例) 12_(0) -> 12_4
3568
3524
  * それ以外の文字列が来た場合は、そのままの値を戻す
3569
- * @param {string} _str
3570
- * @returns
3525
+ * @param {string} _str
3571
3526
  */
3572
3527
  const getKeyPtnName = _str => {
3573
3528
  const regex = /\((\d+)\)/;
@@ -3781,26 +3736,24 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
3781
3736
  newKeyMultiParam(newKey, `pos`, toFloat);
3782
3737
 
3783
3738
  // 各キーの区切り位置 (divX_Y)
3784
- if (_dosObj[`div${newKey}`] !== undefined) {
3785
- const tmpDivs = _dosObj[`div${newKey}`].split(`$`);
3786
- for (let k = 0; k < tmpDivs.length; k++) {
3787
- const tmpDivPtn = tmpDivs[k].split(`,`);
3788
- const ptnName = `${newKey}_${k + dfPtnNum}`;
3789
-
3790
- if (g_keyObj[`div${tmpDivPtn[0]}`] !== undefined) {
3791
- // 既定キーパターンが指定された場合、存在すればその値を適用
3792
- g_keyObj[`div${ptnName}`] = g_keyObj[`div${tmpDivPtn[0]}`];
3793
- g_keyObj[`divMax${ptnName}`] = setVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined, C_TYP_FLOAT);
3794
- } else if (!hasVal(tmpDivPtn[0]) && setIntVal(g_keyObj[`div${ptnName}`], -1) !== -1) {
3795
- // カスタムキー側のdivXが未定義だが、すでに初期設定で定義済みの場合はスキップ
3796
- continue;
3797
- } else {
3798
- // それ以外の場合は指定された値を適用(未指定時はその後で指定)
3799
- g_keyObj[`div${ptnName}`] = setVal(tmpDivPtn[0], undefined, C_TYP_NUMBER);
3800
- g_keyObj[`divMax${ptnName}`] = setVal(tmpDivPtn[1], undefined, C_TYP_FLOAT);
3801
- }
3739
+ _dosObj[`div${newKey}`]?.split(`$`).forEach((tmpDiv, k) => {
3740
+ const tmpDivPtn = tmpDiv.split(`,`);
3741
+ const ptnName = `${newKey}_${k + dfPtnNum}`;
3742
+
3743
+ if (g_keyObj[`div${tmpDivPtn[0]}`] !== undefined) {
3744
+ // 既定キーパターンが指定された場合、存在すればその値を適用
3745
+ g_keyObj[`div${ptnName}`] = g_keyObj[`div${tmpDivPtn[0]}`];
3746
+ g_keyObj[`divMax${ptnName}`] = setVal(g_keyObj[`divMax${tmpDivPtn[0]}`], undefined, C_TYP_FLOAT);
3747
+ } else if (!hasVal(tmpDivPtn[0]) && setIntVal(g_keyObj[`div${ptnName}`], -1) !== -1) {
3748
+ // カスタムキー側のdivXが未定義だが、すでに初期設定で定義済みの場合はスキップ
3749
+ return;
3750
+ } else {
3751
+ // それ以外の場合は指定された値を適用(未指定時はその後で指定)
3752
+ g_keyObj[`div${ptnName}`] = setVal(tmpDivPtn[0], undefined, C_TYP_NUMBER);
3753
+ g_keyObj[`divMax${ptnName}`] = setVal(tmpDivPtn[1], undefined, C_TYP_FLOAT);
3802
3754
  }
3803
- }
3755
+ });
3756
+
3804
3757
  // charaX_Y, posX_Y, keyGroupX_Y, divX_Y, divMaxX_Yが未指定の場合はkeyCtrlX_Yを元に適用
3805
3758
  for (let k = 0; k < g_keyObj.minPatterns; k++) {
3806
3759
  setKeyDfVal(`${newKey}_${k + dfPtnNum}`);
@@ -3950,7 +3903,7 @@ const titleInit = _ => {
3950
3903
  // 変数 titlelineheight の定義 (使用例: |titlelineheight=50|)
3951
3904
  const titlelineheight = (g_headerObj.titlelineheight !== `` ? g_headerObj.titlelineheight - (titlefontsize2 + 10) : 0);
3952
3905
 
3953
- let txtAnimations = [``, ``];
3906
+ const txtAnimations = [``, ``];
3954
3907
  if (!g_headerObj.customTitleAnimationUse) {
3955
3908
  for (let j = 0; j < txtAnimations.length; j++) {
3956
3909
  txtAnimations[j] = `animation-name:${g_headerObj.titleAnimationName[j]};
@@ -4019,7 +3972,6 @@ const titleInit = _ => {
4019
3972
  * @param {string} _id
4020
3973
  * @param {string} _text
4021
3974
  * @param {string} _url
4022
- * @returns
4023
3975
  */
4024
3976
  const createCreditBtn = (_id, _text, _url) =>
4025
3977
  createCss2Button(_id, _text, _ => true,
@@ -4134,10 +4086,10 @@ const titleInit = _ => {
4134
4086
  g_scoreObj.titleFrameNum++;
4135
4087
  g_scoreObj.backTitleFrameNum++;
4136
4088
  g_scoreObj.maskTitleFrameNum++;
4137
- g_timeoutEvtTitleId = setTimeout(_ => flowTitleTimeline(), 1000 / g_fps - buffTime);
4089
+ g_timeoutEvtTitleId = setTimeout(flowTitleTimeline, 1000 / g_fps - buffTime);
4138
4090
  };
4139
4091
 
4140
- g_timeoutEvtTitleId = setTimeout(_ => flowTitleTimeline(), 1000 / g_fps);
4092
+ g_timeoutEvtTitleId = setTimeout(flowTitleTimeline, 1000 / g_fps);
4141
4093
 
4142
4094
  // キー操作イベント(デフォルト)
4143
4095
  setShortcutEvent(g_currentPage, _ => true, { dfEvtFlg: true });
@@ -4332,7 +4284,6 @@ const setSpriteList = _settingList => {
4332
4284
  /**
4333
4285
  * 設定ウィンドウの作成
4334
4286
  * @param {string} _sprite
4335
- * @returns
4336
4287
  */
4337
4288
  const createOptionSprite = _sprite => createEmptySprite(_sprite, `optionsprite`, g_windowObj.optionSprite);
4338
4289
 
@@ -4340,7 +4291,6 @@ const createOptionSprite = _sprite => createEmptySprite(_sprite, `optionsprite`,
4340
4291
  * スライダー共通処理
4341
4292
  * @param {object} _slider
4342
4293
  * @param {object} _link
4343
- * @returns
4344
4294
  */
4345
4295
  const inputSlider = (_slider, _link) => {
4346
4296
  const value = parseInt(_slider.value);
@@ -4364,7 +4314,6 @@ const resetDifWindow = _ => {
4364
4314
  * 次の譜面番号を取得
4365
4315
  * @param {number} _scoreId
4366
4316
  * @param {number} _scrollNum
4367
- * @returns
4368
4317
  */
4369
4318
  const getNextDifficulty = (_scoreId, _scrollNum) => {
4370
4319
  const currentPosIdx = g_headerObj.viewLists.findIndex(val => val === _scoreId);
@@ -4413,7 +4362,6 @@ const makeDifList = (_difList, _targetKey = ``) => {
4413
4362
  /**
4414
4363
  * 譜面セレクター位置の変更ボタン
4415
4364
  * @param {number} _scrollNum
4416
- * @returns
4417
4365
  */
4418
4366
  const makeDifBtn = (_scrollNum = 1) => {
4419
4367
  const dir = _scrollNum === 1 ? `D` : `U`;
@@ -4520,8 +4468,8 @@ const drawSpeedGraph = _scoreId => {
4520
4468
  };
4521
4469
 
4522
4470
  Object.keys(speedObj).forEach(speedType => {
4523
- let frame = speedObj[speedType].frame;
4524
- let speed = speedObj[speedType].speed;
4471
+ const frame = speedObj[speedType].frame;
4472
+ const speed = speedObj[speedType].speed;
4525
4473
  const speedData = g_detailObj[`${speedType}Data`][_scoreId];
4526
4474
 
4527
4475
  if (speedData !== undefined) {
@@ -4624,7 +4572,7 @@ const drawDensityGraph = _scoreId => {
4624
4572
  updateScoreDetailLabel(`Density`, `APM`, obj.apm, 0, g_lblNameObj.s_apm);
4625
4573
  updateScoreDetailLabel(`Density`, `Time`, obj.playingTime, 1, g_lblNameObj.s_time);
4626
4574
  updateScoreDetailLabel(`Density`, `Arrow`, obj.arrowCnts, 3, g_lblNameObj.s_arrow);
4627
- updateScoreDetailLabel(`Density`, `Frz`, obj.frzCnts, 4, g_lblNameObj.s_frz);
4575
+ updateScoreDetailLabel(`Density`, `Frz`, obj.frzCnts, 4, `${g_lblNameObj.s_frz}${g_headerObj.frzStartjdgUse ? ' <span class="common_bold">(2x)</span>' : ''}`);
4628
4576
  };
4629
4577
 
4630
4578
  /**
@@ -4771,7 +4719,8 @@ const makeDifInfo = _scoreId => {
4771
4719
  dataDouji.textContent = g_detailObj.toolDif[_scoreId].douji;
4772
4720
  dataTate.textContent = g_detailObj.toolDif[_scoreId].tate;
4773
4721
  lblArrowInfo2.innerHTML = g_lblNameObj.s_linecnts.split(`{0}`).join(g_detailObj.toolDif[_scoreId].push3cnt);
4774
- dataArrowInfo.innerHTML = `${arrowCnts + frzCnts} <span style="font-size:${g_limitObj.difSelectorSiz}px;">(${arrowCnts} + ${frzCnts})</span>`;
4722
+ dataArrowInfo.innerHTML = `${arrowCnts + frzCnts * (g_headerObj.frzStartjdgUse ? 2 : 1)}
4723
+ <span style="font-size:${g_limitObj.difSelectorSiz}px;">(${arrowCnts} + ${frzCnts}${g_headerObj.frzStartjdgUse ? ' <span class="common_bold">x 2</span>' : ''})</span>`;
4775
4724
  dataArrowInfo2.innerHTML = `<br>(${g_detailObj.arrowCnt[_scoreId]})<br><br>
4776
4725
  (${g_detailObj.frzCnt[_scoreId]})<br><br>
4777
4726
  ${push3CntStr}`.split(`,`).join(`/`);
@@ -4788,8 +4737,6 @@ const makeDifInfo = _scoreId => {
4788
4737
  */
4789
4738
  const setDifficulty = (_initFlg) => {
4790
4739
 
4791
- const getCurrentNo = (_list, _target) => roundZero(_list.findIndex(item => item === _target));
4792
-
4793
4740
  // ---------------------------------------------------
4794
4741
  // 1. キーコンフィグ設定 (KeyConfig)
4795
4742
  g_keyObj.currentKey = g_headerObj.keyLabels[g_stateObj.scoreId];
@@ -4894,11 +4841,13 @@ const setDifficulty = (_initFlg) => {
4894
4841
  g_autoPlaysBase.concat(Object.keys(g_keyObj[`assistPos${g_keyObj.currentKey}_${g_keyObj.currentPtn}`])) :
4895
4842
  g_autoPlaysBase.concat());
4896
4843
 
4897
- // 速度、ゲージ、スクロール、アシスト設定のカーソル位置調整
4844
+ // ゲージ設定及びカーソル位置調整
4845
+ setGauge(0, true);
4846
+
4847
+ // 速度、スクロール、アシスト設定のカーソル位置調整
4898
4848
  if (_initFlg) {
4899
4849
  g_stateObj.speed = g_headerObj.initSpeeds[g_stateObj.scoreId];
4900
4850
  g_settings.speedNum = getCurrentNo(g_settings.speeds, g_stateObj.speed);
4901
- g_settings.gaugeNum = 0;
4902
4851
  }
4903
4852
  g_settings.scrollNum = getCurrentNo(g_settings.scrolls, g_stateObj.scroll);
4904
4853
  g_settings.autoPlayNum = getCurrentNo(g_settings.autoPlays, g_stateObj.autoPlay);
@@ -4951,14 +4900,6 @@ const setDifficulty = (_initFlg) => {
4951
4900
  g_stateObj.autoPlay = g_settings.autoPlays[g_settings.autoPlayNum];
4952
4901
  lnkAutoPlay.textContent = getStgDetailName(g_stateObj.autoPlay);
4953
4902
 
4954
- // ゲージ設定 (Gauge)
4955
- const defaultCustomGauge = g_gaugeOptionObj.custom0 || g_gaugeOptionObj.customDefault;
4956
- if (hasVal(defaultCustomGauge)) {
4957
- g_gaugeOptionObj.custom = (g_gaugeOptionObj[`custom${g_stateObj.scoreId}`] || defaultCustomGauge).concat();
4958
- g_gaugeOptionObj.varCustom = (g_gaugeOptionObj[`varCustom${g_stateObj.scoreId}`] || g_gaugeOptionObj.varCustom0 || g_gaugeOptionObj.varCustomDefault).concat();
4959
- }
4960
- setGauge(0);
4961
-
4962
4903
  // ユーザカスタムイベント(初期)
4963
4904
  g_customJsObj.difficulty.forEach(func => func(_initFlg, g_canLoadDifInfoFlg));
4964
4905
 
@@ -5422,40 +5363,7 @@ const setReverseView = _btn => {
5422
5363
  * ゲージ設定メイン
5423
5364
  * @param {number} _scrollNum
5424
5365
  */
5425
- const setGauge = _scrollNum => {
5426
-
5427
- // カーソルを動かさない場合は先にゲージ設定をリロード
5428
- if (_scrollNum === 0) {
5429
- gaugeChange(g_settings.gaugeNum);
5430
- }
5431
- setSetting(_scrollNum, `gauge`);
5432
-
5433
- // カーソルを動かす場合は設定変更後にゲージ設定を再設定
5434
- if (_scrollNum !== 0) {
5435
- gaugeChange(g_settings.gaugeNum);
5436
- }
5437
- lblGauge2.innerHTML = gaugeFormat(g_stateObj.lifeMode,
5438
- g_stateObj.lifeBorder, g_stateObj.lifeRcv, g_stateObj.lifeDmg, g_stateObj.lifeInit, g_stateObj.lifeVariable);
5439
- };
5440
-
5441
- /**
5442
- * ゲージ設定の切替処理
5443
- * @param {number} _gaugeNum
5444
- */
5445
- const gaugeChange = _gaugeNum => {
5446
- const tmpScoreId = g_stateObj.scoreId;
5447
-
5448
- /**
5449
- * ゲージ詳細変更
5450
- * @param {object} _baseProperty
5451
- * @param {string} _setProperty
5452
- * @param {number} _magnification
5453
- */
5454
- const setLife = (_baseProperty, _setProperty, _magnification = 1) => {
5455
- if (setVal(_baseProperty[tmpScoreId], ``, C_TYP_FLOAT) !== ``) {
5456
- g_stateObj[_setProperty] = _baseProperty[tmpScoreId] * _magnification;
5457
- }
5458
- };
5366
+ const setGauge = (_scrollNum, _gaugeInitFlg = false) => {
5459
5367
 
5460
5368
  /**
5461
5369
  * ゲージ詳細一括変更
@@ -5463,9 +5371,15 @@ const gaugeChange = _gaugeNum => {
5463
5371
  * @param {object} _obj
5464
5372
  */
5465
5373
  const setLifeCategory = (_baseObj, { _magInit = 1, _magRcv = 1, _magDmg = 1 } = {}) => {
5466
- setLife(_baseObj.lifeInits, `lifeInit`, _magInit);
5467
- setLife(_baseObj.lifeRecoverys, `lifeRcv`, _magRcv);
5468
- setLife(_baseObj.lifeDamages, `lifeDmg`, _magDmg);
5374
+ if (hasVal(_baseObj.lifeInits[g_stateObj.scoreId])) {
5375
+ g_stateObj.lifeInit = _baseObj.lifeInits[g_stateObj.scoreId] * _magInit;
5376
+ }
5377
+ if (hasVal(_baseObj.lifeRecoverys[g_stateObj.scoreId])) {
5378
+ g_stateObj.lifeRcv = _baseObj.lifeRecoverys[g_stateObj.scoreId] * _magRcv;
5379
+ }
5380
+ if (hasVal(_baseObj.lifeDamages[g_stateObj.scoreId])) {
5381
+ g_stateObj.lifeDmg = _baseObj.lifeDamages[g_stateObj.scoreId] * _magDmg;
5382
+ }
5469
5383
  };
5470
5384
 
5471
5385
  /**
@@ -5473,56 +5387,68 @@ const gaugeChange = _gaugeNum => {
5473
5387
  * @param {object} _baseObj
5474
5388
  */
5475
5389
  const changeLifeMode = (_baseObj) => {
5476
- if (_baseObj.lifeBorders[tmpScoreId] === `x`) {
5390
+ if (_baseObj.lifeBorders[g_stateObj.scoreId] === `x`) {
5477
5391
  g_stateObj.lifeBorder = 0;
5478
5392
  g_stateObj.lifeMode = C_LFE_SURVIVAL;
5479
5393
  } else {
5480
- g_stateObj.lifeBorder = _baseObj.lifeBorders[tmpScoreId];
5394
+ g_stateObj.lifeBorder = _baseObj.lifeBorders[g_stateObj.scoreId];
5481
5395
  g_stateObj.lifeMode = C_LFE_BORDER;
5482
5396
  }
5483
5397
  };
5484
5398
 
5485
5399
  // ゲージ初期化
5486
- if (_gaugeNum === 0) {
5487
- if (hasVal(g_headerObj.lifeBorders[tmpScoreId])) {
5488
- changeLifeMode(g_headerObj);
5489
- g_gaugeType = (g_gaugeOptionObj.custom.length > 0 ? C_LFE_CUSTOM : g_stateObj.lifeMode);
5490
-
5491
- g_stateObj.lifeVariable = g_gaugeOptionObj[`var${g_gaugeType}`][_gaugeNum];
5492
- g_settings.gauges = structuredClone(g_gaugeOptionObj[g_gaugeType.toLowerCase()]);
5493
- g_stateObj.gauge = g_settings.gauges[g_settings.gaugeNum];
5400
+ if (_gaugeInitFlg) {
5401
+ // カスタムゲージの設定取得
5402
+ const defaultCustomGauge = g_gaugeOptionObj.custom0 || g_gaugeOptionObj.customDefault;
5403
+ if (hasVal(defaultCustomGauge)) {
5404
+ g_gaugeOptionObj.custom = (g_gaugeOptionObj[`custom${g_stateObj.scoreId}`] || defaultCustomGauge).concat();
5405
+ g_gaugeOptionObj.varCustom = (g_gaugeOptionObj[`varCustom${g_stateObj.scoreId}`] || g_gaugeOptionObj.varCustom0 || g_gaugeOptionObj.varCustomDefault).concat();
5494
5406
  }
5495
- setLifeCategory(g_headerObj);
5496
5407
 
5497
- } else {
5498
- // 設定されたゲージ設定、カーソルに合わせて設定値を更新
5499
- g_stateObj.lifeVariable = g_gaugeOptionObj[`var${g_gaugeType}`][_gaugeNum];
5500
- if (g_gaugeOptionObj.custom.length === 0 ||
5501
- g_gaugeOptionObj.defaultList.includes(g_gaugeOptionObj[`defaultGauge${tmpScoreId}`])) {
5502
- const gType = (g_gaugeType === C_LFE_CUSTOM ?
5503
- toCapitalize(g_gaugeOptionObj[`defaultGauge${tmpScoreId}`]) : g_gaugeType);
5504
- g_stateObj.lifeMode = g_gaugeOptionObj[`type${gType}`][_gaugeNum];
5505
- g_stateObj.lifeBorder = g_gaugeOptionObj[`clear${gType}`][_gaugeNum];
5506
- g_stateObj.lifeInit = g_gaugeOptionObj[`init${gType}`][_gaugeNum];
5507
- g_stateObj.lifeRcv = g_gaugeOptionObj[`rcv${gType}`][_gaugeNum];
5508
- g_stateObj.lifeDmg = g_gaugeOptionObj[`dmg${gType}`][_gaugeNum];
5509
- }
5408
+ // ゲージタイプの設定
5409
+ changeLifeMode(g_headerObj);
5410
+ g_gaugeType = (g_gaugeOptionObj.custom.length > 0 ? C_LFE_CUSTOM : g_stateObj.lifeMode);
5411
+
5412
+ // ゲージ配列を入れ替え
5413
+ g_settings.gauges = structuredClone(g_gaugeOptionObj[g_gaugeType.toLowerCase()]);
5414
+ g_settings.gaugeNum = getCurrentNo(g_settings.gauges, g_stateObj.gauge);
5415
+ g_stateObj.gauge = g_settings.gauges[g_settings.gaugeNum];
5416
+ }
5417
+ setSetting(_scrollNum, `gauge`);
5418
+ g_stateObj.lifeVariable = g_gaugeOptionObj[`var${g_gaugeType}`][g_settings.gaugeNum];
5419
+
5420
+ // デフォルトゲージの設定を適用(g_gaugeOptionObjから取得)
5421
+ if (g_gaugeOptionObj.custom.length === 0 ||
5422
+ g_gaugeOptionObj.defaultList.includes(g_gaugeOptionObj[`defaultGauge${g_stateObj.scoreId}`])) {
5423
+
5424
+ const gType = (g_gaugeType === C_LFE_CUSTOM ?
5425
+ toCapitalize(g_gaugeOptionObj[`defaultGauge${g_stateObj.scoreId}`]) : g_gaugeType);
5426
+ const getGaugeVal = _type => g_gaugeOptionObj[`${_type}${gType}`][g_settings.gaugeNum];
5427
+ g_stateObj.lifeMode = getGaugeVal(`type`);
5428
+ g_stateObj.lifeBorder = getGaugeVal(`clear`);
5429
+ g_stateObj.lifeInit = getGaugeVal(`init`);
5430
+ g_stateObj.lifeRcv = getGaugeVal(`rcv`);
5431
+ g_stateObj.lifeDmg = getGaugeVal(`dmg`);
5510
5432
  }
5511
5433
 
5512
- // ゲージ設定(Light, Easy)の初期化
5513
- if (g_stateObj.gauge === `Light` || g_stateObj.gauge === `Easy`) {
5514
- setLifeCategory(g_headerObj, { _magRcv: 2 });
5434
+ // デフォルトゲージの初期設定(Light, Easyでは回復量を2倍にする)
5435
+ if ([`Original`, `Light`, `Normal`, `Easy`].includes(g_stateObj.gauge)) {
5436
+ setLifeCategory(g_headerObj, { _magRcv: [`Light`, `Easy`].includes(g_stateObj.gauge) ? 2 : 1 });
5515
5437
  }
5516
5438
 
5517
5439
  // ゲージ設定別に個別設定した場合はここで設定を上書き
5518
5440
  // 譜面ヘッダー:gaugeXXX で設定した値がここで適用される
5519
5441
  if (hasVal(g_gaugeOptionObj[`gauge${g_stateObj.gauge}s`])) {
5520
5442
  const tmpGaugeObj = g_gaugeOptionObj[`gauge${g_stateObj.gauge}s`];
5521
- if (hasVal(tmpGaugeObj.lifeBorders[tmpScoreId])) {
5443
+ if (hasVal(tmpGaugeObj.lifeBorders[g_stateObj.scoreId])) {
5522
5444
  changeLifeMode(tmpGaugeObj);
5523
5445
  }
5524
5446
  setLifeCategory(tmpGaugeObj);
5525
5447
  }
5448
+
5449
+ // ゲージ詳細情報を表示
5450
+ lblGauge2.innerHTML = gaugeFormat(g_stateObj.lifeMode,
5451
+ g_stateObj.lifeBorder, g_stateObj.lifeRcv, g_stateObj.lifeDmg, g_stateObj.lifeInit, g_stateObj.lifeVariable);
5526
5452
  };
5527
5453
 
5528
5454
  /**
@@ -5533,7 +5459,6 @@ const gaugeChange = _gaugeNum => {
5533
5459
  * @param {number} _dmg
5534
5460
  * @param {number} _init
5535
5461
  * @param {string} _lifeValFlg
5536
- * @returns
5537
5462
  */
5538
5463
  const gaugeFormat = (_mode, _border, _rcv, _dmg, _init, _lifeValFlg) => {
5539
5464
  const initVal = g_headerObj.maxLifeVal * _init / 100;
@@ -5610,7 +5535,6 @@ const gaugeFormat = (_mode, _border, _rcv, _dmg, _init, _lifeValFlg) => {
5610
5535
  * @param {number} _dmg
5611
5536
  * @param {number} _init
5612
5537
  * @param {number} _allCnt
5613
- * @returns
5614
5538
  */
5615
5539
  const getAccuracy = (_border, _rcv, _dmg, _init, _allCnt) => {
5616
5540
  const justPoint = _rcv + _dmg > 0 ? Math.max(_border - _init + _dmg * _allCnt, 0) / (_rcv + _dmg) : 0;
@@ -5668,9 +5592,7 @@ const getKeyCtrl = (_localStorage, _extraKeyName = ``) => {
5668
5592
  g_keyObj[`${header}${copyPtn}`] = structuredClone(g_keyObj[`${header}${basePtn}`]);
5669
5593
  }
5670
5594
  });
5671
- g_keyCopyLists.simple.forEach(header => {
5672
- g_keyObj[`${header}${copyPtn}`] = g_keyObj[`${header}${basePtn}`];
5673
- });
5595
+ g_keyCopyLists.simple.forEach(header => g_keyObj[`${header}${copyPtn}`] = g_keyObj[`${header}${basePtn}`]);
5674
5596
 
5675
5597
  g_keycons.groups.forEach(type => {
5676
5598
  let maxPtn = 0;
@@ -5892,11 +5814,10 @@ const createSettingsDisplayWindow = _sprite => {
5892
5814
  appearanceSlider.addEventListener(`input`, _ =>
5893
5815
  g_hidSudObj.filterPos = inputSlider(appearanceSlider, lblAppearancePos), false);
5894
5816
 
5895
- const dispAppearanceSlider = _ => {
5817
+ const dispAppearanceSlider = _ =>
5896
5818
  [`lblAppearancePos`, `lblAppearanceBar`, `lnkLockBtn`, `lnkfilterLine`].forEach(obj =>
5897
5819
  $id(obj).visibility = g_appearanceRanges.includes(g_stateObj.appearance) ? `Visible` : `Hidden`
5898
5820
  );
5899
- };
5900
5821
  dispAppearanceSlider();
5901
5822
 
5902
5823
  // ---------------------------------------------------
@@ -6048,7 +5969,6 @@ const keyConfigInit = (_kcType = g_kcType) => {
6048
5969
  * @param {number} _len
6049
5970
  * @param {number} _j
6050
5971
  * @param {number} _scrollNum
6051
- * @returns
6052
5972
  */
6053
5973
  const changeTmpData = (_type, _len, _j, _scrollNum) => {
6054
5974
  const tmpNo = nextPos(g_keyObj[`${_type}${keyCtrlPtn}_${g_keycons[`${_type}GroupNum`]}`][_j], _scrollNum, _len);
@@ -6241,7 +6161,6 @@ const keyConfigInit = (_kcType = g_kcType) => {
6241
6161
  * @param {string} _directionFlg
6242
6162
  * @param {function} _func
6243
6163
  * @param {*} object (x, y, w, h, siz)
6244
- * @returns
6245
6164
  */
6246
6165
  const makeMiniKCButton = (_id, _directionFlg, _func, { x = g_sWidth * 5 / 6 - 30, y = 15, w = 15, h = 20, siz = g_limitObj.mainSiz } = {}) => {
6247
6166
  return createCss2Button(`${_id}${_directionFlg}`, g_settingBtnObj.chara[_directionFlg], _func,
@@ -6519,7 +6438,6 @@ const keyConfigInit = (_kcType = g_kcType) => {
6519
6438
  * @param {number} _tempPtn
6520
6439
  * @param {number} _sign
6521
6440
  * @param {boolean} _transKeyUse
6522
- * @returns
6523
6441
  */
6524
6442
  const searchPattern = (_tempPtn, _sign, _transKeyUse = false, _skipFlg = false) => {
6525
6443
  let nextPtn = _tempPtn + _sign;
@@ -6710,14 +6628,12 @@ const keyConfigInit = (_kcType = g_kcType) => {
6710
6628
  * 影矢印色の取得
6711
6629
  * @param {number} _colorPos
6712
6630
  * @param {string} _arrowColor
6713
- * @returns
6714
6631
  */
6715
6632
  const getShadowColor = (_colorPos, _arrowColor) => g_headerObj.setShadowColor[_colorPos] === `Default` ?
6716
6633
  _arrowColor : g_headerObj.setShadowColor[_colorPos];
6717
6634
 
6718
6635
  /**
6719
6636
  * キー数基礎情報の取得
6720
- * @returns
6721
6637
  */
6722
6638
  const getKeyInfo = _ => {
6723
6639
  const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
@@ -7014,9 +6930,7 @@ const loadingScoreInit = async () => {
7014
6930
  // キーパターン(デフォルト)に対応する矢印番号を格納
7015
6931
  convertReplaceNums();
7016
6932
 
7017
- const setData = (_data, _minLength = 1) => {
7018
- return (hasArrayList(_data, _minLength) ? _data.concat() : []);
7019
- };
6933
+ const setData = (_data, _minLength = 1) => hasArrayList(_data, _minLength) ? _data.concat() : [];
7020
6934
 
7021
6935
  // フレーム・曲開始位置調整
7022
6936
  let preblankFrame = 0;
@@ -7040,9 +6954,8 @@ const loadingScoreInit = async () => {
7040
6954
  });
7041
6955
  }
7042
6956
 
7043
- Object.keys(g_dataMinObj).forEach(dataType => {
7044
- g_scoreObj[`${dataType}Data`] = setData(tmpObj[`${dataType}Data`], g_dataMinObj[dataType]);
7045
- });
6957
+ Object.keys(g_dataMinObj).forEach(dataType =>
6958
+ g_scoreObj[`${dataType}Data`] = setData(tmpObj[`${dataType}Data`], g_dataMinObj[dataType]));
7046
6959
 
7047
6960
  lastFrame += preblankFrame;
7048
6961
  firstArrowFrame += preblankFrame;
@@ -7392,7 +7305,6 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7392
7305
  /**
7393
7306
  * 個別・全体色変化データをマージして整列し、単純配列として返却
7394
7307
  * @param {string} _header
7395
- * @returns
7396
7308
  */
7397
7309
  const mergeColorData = (_header = ``) => {
7398
7310
  if (obj[`color${_header}Data`] === undefined) return [];
@@ -7492,7 +7404,6 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7492
7404
  * 例) |backA2_data=back_data| -> back_dataで定義された値を使用
7493
7405
  * @param {string} _header
7494
7406
  * @param {string} _dataName
7495
- * @returns
7496
7407
  */
7497
7408
  const getRefData = (_header, _dataName) => {
7498
7409
  const data = _dosObj[`${_header}${_dataName}`];
@@ -7504,7 +7415,6 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7504
7415
  * @param {string} _header
7505
7416
  * @param {string} _type
7506
7417
  * @param {number} _scoreNo
7507
- * @returns
7508
7418
  */
7509
7419
  const getPriorityList = (_header, _type, _scoreNo) => [
7510
7420
  getRefData(_header, `${_type}${g_localeObj.val}${_scoreNo}_data`),
@@ -7515,7 +7425,6 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7515
7425
 
7516
7426
  /**
7517
7427
  * 歌詞表示、背景・マスクデータの優先順取得
7518
- * @returns
7519
7428
  */
7520
7429
  const getPriorityHeader = _ => {
7521
7430
  const list = [];
@@ -7711,9 +7620,8 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
7711
7620
  obj.backMaxDepth = -1;
7712
7621
  if (g_stateObj.d_background === C_FLG_OFF) {
7713
7622
  } else {
7714
- g_animationData.forEach(sprite => {
7715
- [obj[`${sprite}Data`], obj[`${sprite}MaxDepth`]] = makeBackgroundData(sprite, scoreIdHeader);
7716
- });
7623
+ g_animationData.forEach(sprite =>
7624
+ [obj[`${sprite}Data`], obj[`${sprite}MaxDepth`]] = makeBackgroundData(sprite, scoreIdHeader));
7717
7625
  }
7718
7626
 
7719
7627
  // 結果画面用・背景/マスクデータの分解 (下記すべてで1セット、改行区切り)
@@ -7874,7 +7782,6 @@ const setMotionOnFrame = _ => g_motionFunc[g_stateObj.motion]([...Array(g_sHeigh
7874
7782
  * @param {array} _frms
7875
7783
  * @param {number} _spd
7876
7784
  * @param {number} _pnFlg 正負(1 もしくは -1)
7877
- * @returns
7878
7785
  */
7879
7786
  const getBoostTrace = (_frms, _spd, _pnFlg = 1) => {
7880
7787
  for (let j = C_MOTION_STD_POS + 1; j < C_MOTION_STD_POS + 70; j++) {
@@ -7887,7 +7794,6 @@ const getBoostTrace = (_frms, _spd, _pnFlg = 1) => {
7887
7794
  * Brake用の適用関数
7888
7795
  * - 初期は+2x、ステップゾーンに近づくにつれて加速量を下げる (20 → 34)
7889
7796
  * @param {array} _frms
7890
- * @returns
7891
7797
  */
7892
7798
  const getBrakeTrace = _frms => {
7893
7799
  for (let j = C_MOTION_STD_POS + 5; j < C_MOTION_STD_POS + 19; j++) {
@@ -8083,7 +7989,6 @@ const pushArrows = (_dataObj, _speedOnFrame, _motionOnFrame, _firstArrivalFrame)
8083
7989
  * @param {string} _header
8084
7990
  * @param {function} _setFunc
8085
7991
  * @param {object} obj _colorFlg: 個別色変化フラグ, _calcFrameFlg: 逆算を無条件で行うかどうかの可否
8086
- * @returns
8087
7992
  */
8088
7993
  const calcDataTiming = (_type, _header, _setFunc = _ => true,
8089
7994
  { _term = 4, _colorFlg = false, _calcFrameFlg = false } = {}) => {
@@ -8124,7 +8029,6 @@ const pushArrows = (_dataObj, _speedOnFrame, _motionOnFrame, _firstArrivalFrame)
8124
8029
  * 歌詞表示、背景・マスク表示のフェードイン時調整処理
8125
8030
  * @param {string} _type
8126
8031
  * @param {object} _data
8127
- * @returns
8128
8032
  */
8129
8033
  const calcAnimationData = (_type, _data) => {
8130
8034
 
@@ -9027,10 +8931,9 @@ const mainInit = _ => {
9027
8931
  Ii: [`ii`, 0], Shakin: [`shakin`, 1], Matari: [`matari`, 2], Shobon: [`shobon`, 3], Uwan: [`uwan`, 4],
9028
8932
  MCombo: [`combo`, 5], Kita: [`kita`, 7], Iknai: [`iknai`, 8], FCombo: [`combo`, 9],
9029
8933
  };
9030
- Object.keys(jdgMainScoreObj).forEach(jdgScore => {
8934
+ Object.keys(jdgMainScoreObj).forEach(jdgScore =>
9031
8935
  infoSprite.appendChild(makeCounterSymbol(`lbl${jdgScore}`, g_headerObj.playingWidth - 110,
9032
- g_cssObj[`common_${jdgMainScoreObj[jdgScore][0]}`], jdgMainScoreObj[jdgScore][1] + 1, 0, g_workObj.scoreDisp));
9033
- });
8936
+ g_cssObj[`common_${jdgMainScoreObj[jdgScore][0]}`], jdgMainScoreObj[jdgScore][1] + 1, 0, g_workObj.scoreDisp)));
9034
8937
 
9035
8938
  // パーフェクト演出
9036
8939
  judgeSprite.appendChild(createDivCss2Label(`finishView`, ``, g_lblPosObj.finishView, g_cssObj.common_kita));
@@ -9247,12 +9150,12 @@ const mainInit = _ => {
9247
9150
  * @param _deleteObj 削除オブジェクト
9248
9151
  */
9249
9152
  const judgeObjDelete = {};
9250
- g_typeLists.arrow.forEach(type => {
9153
+ g_typeLists.arrow.forEach(type =>
9251
9154
  judgeObjDelete[type] = (_j, _deleteName) => {
9252
9155
  g_workObj[`judg${toCapitalize(type)}Cnt`][_j]++;
9253
9156
  arrowSprite[g_attrObj[_deleteName].dividePos].removeChild(document.getElementById(_deleteName));
9254
- }
9255
- });
9157
+ delete g_attrObj[_deleteName];
9158
+ });
9256
9159
 
9257
9160
  /**
9258
9161
  * 自動判定
@@ -9754,28 +9657,20 @@ const mainInit = _ => {
9754
9657
  changeStepY(currentFrame);
9755
9658
 
9756
9659
  // ダミー矢印生成(背面に表示するため先に処理)
9757
- if (g_workObj.mkDummyArrow[currentFrame] !== undefined) {
9758
- g_workObj.mkDummyArrow[currentFrame].forEach(data =>
9759
- makeArrow(data, ++dummyArrowCnts[data], `dummyArrow`, g_workObj.dummyArrowColors[data]));
9760
- }
9660
+ g_workObj.mkDummyArrow[currentFrame]?.forEach(data =>
9661
+ makeArrow(data, ++dummyArrowCnts[data], `dummyArrow`, g_workObj.dummyArrowColors[data]));
9761
9662
 
9762
9663
  // 矢印生成
9763
- if (g_workObj.mkArrow[currentFrame] !== undefined) {
9764
- g_workObj.mkArrow[currentFrame].forEach(data =>
9765
- makeArrow(data, ++arrowCnts[data], `arrow`, g_workObj.arrowColors[data]));
9766
- }
9664
+ g_workObj.mkArrow[currentFrame]?.forEach(data =>
9665
+ makeArrow(data, ++arrowCnts[data], `arrow`, g_workObj.arrowColors[data]));
9767
9666
 
9768
9667
  // ダミーフリーズアロー生成
9769
- if (g_workObj.mkDummyFrzArrow[currentFrame] !== undefined) {
9770
- g_workObj.mkDummyFrzArrow[currentFrame].forEach(data =>
9771
- makeFrzArrow(data, ++dummyFrzCnts[data], `dummyFrz`, g_workObj.dummyFrzNormalColors[data], g_workObj.dummyFrzNormalBarColors[data]));
9772
- }
9668
+ g_workObj.mkDummyFrzArrow[currentFrame]?.forEach(data =>
9669
+ makeFrzArrow(data, ++dummyFrzCnts[data], `dummyFrz`, g_workObj.dummyFrzNormalColors[data], g_workObj.dummyFrzNormalBarColors[data]));
9773
9670
 
9774
9671
  // フリーズアロー生成
9775
- if (g_workObj.mkFrzArrow[currentFrame] !== undefined) {
9776
- g_workObj.mkFrzArrow[currentFrame].forEach(data =>
9777
- makeFrzArrow(data, ++frzCnts[data], `frz`, g_workObj.frzNormalColors[data], g_workObj.frzNormalBarColors[data]));
9778
- }
9672
+ g_workObj.mkFrzArrow[currentFrame]?.forEach(data =>
9673
+ makeFrzArrow(data, ++frzCnts[data], `frz`, g_workObj.frzNormalColors[data], g_workObj.frzNormalBarColors[data]));
9779
9674
 
9780
9675
  // 矢印・フリーズアロー移動&消去
9781
9676
  for (let j = 0; j < keyNum; j++) {
@@ -9812,56 +9707,54 @@ const mainInit = _ => {
9812
9707
  }
9813
9708
 
9814
9709
  // 歌詞表示
9815
- if (g_scoreObj.wordData[currentFrame] !== undefined) {
9816
- g_scoreObj.wordData[currentFrame].forEach(tmpObj => {
9817
- g_wordObj.wordDir = tmpObj[0];
9818
- g_wordObj.wordDat = tmpObj[1];
9819
- g_wordSprite = document.querySelector(`#lblword${g_wordObj.wordDir}`);
9710
+ g_scoreObj.wordData[currentFrame]?.forEach(tmpObj => {
9711
+ g_wordObj.wordDir = tmpObj[0];
9712
+ g_wordObj.wordDat = tmpObj[1];
9713
+ g_wordSprite = document.querySelector(`#lblword${g_wordObj.wordDir}`);
9820
9714
 
9821
- const wordDepth = Number(g_wordObj.wordDir);
9822
- if (g_wordObj.wordDat.substring(0, 5) === `[fade`) {
9715
+ const wordDepth = Number(g_wordObj.wordDir);
9716
+ if (g_wordObj.wordDat.substring(0, 5) === `[fade`) {
9823
9717
 
9824
- // フェードイン・アウト開始
9825
- const fkey = fadeFlgs[Object.keys(fadeFlgs).find(flg => g_wordObj.wordDat === `[${flg}]`)];
9826
- g_wordObj[`fade${fkey[0]}Flg${wordDepth}`] = true;
9827
- g_wordObj[`fade${fkey[1]}Flg${wordDepth}`] = false;
9828
- g_wordSprite.style.animationName =
9829
- `fade${fkey[0]}${(++g_workObj[`fade${fkey[0]}No`][wordDepth] % 2)}`;
9718
+ // フェードイン・アウト開始
9719
+ const fkey = fadeFlgs[Object.keys(fadeFlgs).find(flg => g_wordObj.wordDat === `[${flg}]`)];
9720
+ g_wordObj[`fade${fkey[0]}Flg${wordDepth}`] = true;
9721
+ g_wordObj[`fade${fkey[1]}Flg${wordDepth}`] = false;
9722
+ g_wordSprite.style.animationName =
9723
+ `fade${fkey[0]}${(++g_workObj[`fade${fkey[0]}No`][wordDepth] % 2)}`;
9830
9724
 
9831
- g_workObj.lastFadeFrame[wordDepth] = currentFrame;
9832
- g_workObj.wordFadeFrame[wordDepth] = (tmpObj.length > 2 ?
9833
- setIntVal(tmpObj[2], C_WOD_FRAME) : C_WOD_FRAME);
9725
+ g_workObj.lastFadeFrame[wordDepth] = currentFrame;
9726
+ g_workObj.wordFadeFrame[wordDepth] = (tmpObj.length > 2 ?
9727
+ setIntVal(tmpObj[2], C_WOD_FRAME) : C_WOD_FRAME);
9834
9728
 
9835
- g_wordSprite.style.animationDuration = `${g_workObj.wordFadeFrame[wordDepth] / g_fps}s`;
9836
- g_wordSprite.style.animationTimingFunction = `linear`;
9837
- g_wordSprite.style.animationFillMode = `forwards`;
9729
+ g_wordSprite.style.animationDuration = `${g_workObj.wordFadeFrame[wordDepth] / g_fps}s`;
9730
+ g_wordSprite.style.animationTimingFunction = `linear`;
9731
+ g_wordSprite.style.animationFillMode = `forwards`;
9838
9732
 
9839
- } else if ([`[center]`, `[left]`, `[right]`].includes(g_wordObj.wordDat)) {
9733
+ } else if ([`[center]`, `[left]`, `[right]`].includes(g_wordObj.wordDat)) {
9840
9734
 
9841
- // 歌詞位置変更
9842
- g_wordSprite.style.textAlign = g_wordObj.wordDat.slice(1, -1);
9735
+ // 歌詞位置変更
9736
+ g_wordSprite.style.textAlign = g_wordObj.wordDat.slice(1, -1);
9843
9737
 
9844
- } else if (/\[fontSize=\d+\]/.test(g_wordObj.wordDat)) {
9738
+ } else if (/\[fontSize=\d+\]/.test(g_wordObj.wordDat)) {
9845
9739
 
9846
- // フォントサイズ変更
9847
- const fontSize = setIntVal(g_wordObj.wordDat.match(/\d+/)[0], g_limitObj.mainSiz);
9848
- g_wordSprite.style.fontSize = `${fontSize}px`;
9740
+ // フォントサイズ変更
9741
+ const fontSize = setIntVal(g_wordObj.wordDat.match(/\d+/)[0], g_limitObj.mainSiz);
9742
+ g_wordSprite.style.fontSize = `${fontSize}px`;
9849
9743
 
9850
- } else {
9744
+ } else {
9851
9745
 
9852
- // フェードイン・アウト処理後、表示する歌詞を表示
9853
- const fadingFlg = currentFrame - g_workObj.lastFadeFrame[wordDepth] >= g_workObj.wordFadeFrame[wordDepth];
9854
- [`Out`, `In`].forEach(pattern => {
9855
- if (g_wordObj[`fade${pattern}Flg${g_wordObj.wordDir}`] && fadingFlg) {
9856
- g_wordSprite.style.animationName = `none`;
9857
- g_wordObj[`fade${pattern}Flg${g_wordObj.wordDir}`] = false;
9858
- }
9859
- });
9860
- g_workObj[`word${g_wordObj.wordDir}Data`] = g_wordObj.wordDat;
9861
- g_wordSprite.innerHTML = g_wordObj.wordDat;
9862
- }
9863
- });
9864
- }
9746
+ // フェードイン・アウト処理後、表示する歌詞を表示
9747
+ const fadingFlg = currentFrame - g_workObj.lastFadeFrame[wordDepth] >= g_workObj.wordFadeFrame[wordDepth];
9748
+ [`Out`, `In`].forEach(pattern => {
9749
+ if (g_wordObj[`fade${pattern}Flg${g_wordObj.wordDir}`] && fadingFlg) {
9750
+ g_wordSprite.style.animationName = `none`;
9751
+ g_wordObj[`fade${pattern}Flg${g_wordObj.wordDir}`] = false;
9752
+ }
9753
+ });
9754
+ g_workObj[`word${g_wordObj.wordDir}Data`] = g_wordObj.wordDat;
9755
+ g_wordSprite.innerHTML = g_wordObj.wordDat;
9756
+ }
9757
+ });
9865
9758
 
9866
9759
  // 判定キャラクタ消去
9867
9760
  jdgGroups.forEach(jdg => {
@@ -9912,7 +9805,7 @@ const mainInit = _ => {
9912
9805
  }
9913
9806
  g_scoreObj.frameNum++;
9914
9807
  g_scoreObj.baseFrame++;
9915
- g_timeoutEvtId = setTimeout(_ => flowTimeline(), 1000 / g_fps - buffTime);
9808
+ g_timeoutEvtId = setTimeout(flowTimeline, 1000 / g_fps - buffTime);
9916
9809
  }
9917
9810
  };
9918
9811
  g_skinJsObj.main.forEach(func => func());
@@ -9927,7 +9820,7 @@ const mainInit = _ => {
9927
9820
  g_audio.play(musicStartAdjustment);
9928
9821
  }
9929
9822
 
9930
- g_timeoutEvtId = setTimeout(_ => flowTimeline(), 1000 / g_fps);
9823
+ g_timeoutEvtId = setTimeout(flowTimeline, 1000 / g_fps);
9931
9824
  };
9932
9825
 
9933
9826
  /**
@@ -10033,50 +9926,33 @@ const changeColors = (_mkColor, _mkColorCd, _header, _name) => {
10033
9926
  * @param {number} _frameNum
10034
9927
  */
10035
9928
  const changeCssMotions = (_header, _name, _frameNum) => {
10036
-
10037
9929
  const camelHeader = _header === `` ? _name : `${_header}${toCapitalize(_name)}`;
10038
- const frameData = g_workObj[`mk${toCapitalize(camelHeader)}CssMotion`][_frameNum];
10039
-
10040
- if (frameData !== undefined) {
10041
- for (let j = 0; j < frameData.length; j++) {
10042
- const targetj = frameData[j];
10043
- g_workObj[`${camelHeader}CssMotions`][targetj] =
10044
- g_workObj[`mk${toCapitalize(camelHeader)}CssMotionName`][_frameNum][2 * j + g_workObj.dividePos[targetj]];
10045
- }
10046
- }
9930
+ g_workObj[`mk${toCapitalize(camelHeader)}CssMotion`][_frameNum]?.forEach((targetj, j) =>
9931
+ g_workObj[`${camelHeader}CssMotions`][targetj] =
9932
+ g_workObj[`mk${toCapitalize(camelHeader)}CssMotionName`][_frameNum][2 * j + g_workObj.dividePos[targetj]]);
10047
9933
  };
10048
9934
 
10049
9935
  /**
10050
9936
  * スクロール方向の変更(矢印・フリーズアロー)
10051
9937
  * @param {number} _frameNum
10052
9938
  */
10053
- const changeScrollArrowDirs = (_frameNum) => {
10054
- const frameData = g_workObj.mkScrollchArrow[_frameNum];
10055
- if (frameData !== undefined) {
10056
- for (let j = 0; j < frameData.length; j++) {
10057
- const targetj = frameData[j];
10058
- g_workObj.scrollDir[targetj] = g_workObj.scrollDirDefault[targetj] * g_workObj.mkScrollchArrowDir[_frameNum][j];
10059
- g_workObj.dividePos[targetj] = (g_workObj.scrollDir[targetj] === 1 ? 0 : 1);
10060
- }
10061
- }
10062
- };
9939
+ const changeScrollArrowDirs = (_frameNum) =>
9940
+ g_workObj.mkScrollchArrow[_frameNum]?.forEach((targetj, j) => {
9941
+ g_workObj.scrollDir[targetj] = g_workObj.scrollDirDefault[targetj] * g_workObj.mkScrollchArrowDir[_frameNum][j];
9942
+ g_workObj.dividePos[targetj] = (g_workObj.scrollDir[targetj] === 1 ? 0 : 1);
9943
+ });
10063
9944
 
10064
9945
  /**
10065
9946
  * ステップゾーンの位置反転
10066
9947
  * @param {number} _frameNum
10067
9948
  */
10068
- const changeStepY = (_frameNum) => {
10069
- const frameData = g_workObj.mkScrollchStep[_frameNum];
10070
- if (frameData !== undefined) {
10071
- for (let j = 0; j < frameData.length; j++) {
10072
- const targetj = frameData[j];
10073
- const dividePos = (g_workObj.scrollDirDefault[targetj] * g_workObj.mkScrollchStepDir[_frameNum][j] === 1 ? 0 : 1);
10074
- const baseY = C_STEP_Y + g_posObj.reverseStepY * dividePos;
10075
- $id(`stepRoot${targetj}`).top = `${baseY}px`;
10076
- $id(`frzHit${targetj}`).top = `${baseY}px`;
10077
- }
10078
- }
10079
- };
9949
+ const changeStepY = (_frameNum) =>
9950
+ g_workObj.mkScrollchStep[_frameNum]?.forEach((targetj, j) => {
9951
+ const dividePos = (g_workObj.scrollDirDefault[targetj] * g_workObj.mkScrollchStepDir[_frameNum][j] === 1 ? 0 : 1);
9952
+ const baseY = C_STEP_Y + g_posObj.reverseStepY * dividePos;
9953
+ $id(`stepRoot${targetj}`).top = `${baseY}px`;
9954
+ $id(`frzHit${targetj}`).top = `${baseY}px`;
9955
+ });
10080
9956
 
10081
9957
  /**
10082
9958
  * フリーズアローヒット時の描画変更
@@ -10597,9 +10473,8 @@ const resultInit = _ => {
10597
10473
 
10598
10474
  const mTitleForView = [g_headerObj.musicTitleForView[0], g_headerObj.musicTitleForView[1] || ``];
10599
10475
  if (g_headerObj.musicTitlesForView[g_headerObj.musicNos[g_stateObj.scoreId]] !== undefined) {
10600
- mTitleForView.forEach((mTitle, j) => {
10601
- mTitleForView[j] = g_headerObj.musicTitlesForView[g_headerObj.musicNos[g_stateObj.scoreId]][j];
10602
- });
10476
+ mTitleForView.forEach((mTitle, j) =>
10477
+ mTitleForView[j] = g_headerObj.musicTitlesForView[g_headerObj.musicNos[g_stateObj.scoreId]][j]);
10603
10478
  }
10604
10479
 
10605
10480
  const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
@@ -10685,12 +10560,11 @@ const resultInit = _ => {
10685
10560
  };
10686
10561
 
10687
10562
  // キャラクタ、スコア描画
10688
- Object.keys(jdgScoreObj).forEach(score => {
10563
+ Object.keys(jdgScoreObj).forEach(score =>
10689
10564
  multiAppend(resultWindow,
10690
10565
  makeCssResultSymbol(`lbl${jdgScoreObj[score].id}`, 0, g_cssObj[`common_${jdgScoreObj[score].color}`], jdgScoreObj[score].pos, jdgScoreObj[score].label),
10691
10566
  makeCssResultSymbol(`lbl${jdgScoreObj[score].id}S`, 50, g_cssObj.common_score, jdgScoreObj[score].pos, g_resultObj[score], C_ALIGN_RIGHT),
10692
- );
10693
- });
10567
+ ));
10694
10568
  if (g_stateObj.autoAll === C_FLG_OFF) {
10695
10569
  multiAppend(resultWindow,
10696
10570
  makeCssResultSymbol(`lblFast`, 350, g_cssObj.common_matari, 0, g_lblNameObj.j_fast),
@@ -10859,9 +10733,8 @@ const resultInit = _ => {
10859
10733
  [`[url]`, g_isLocal ? `` : `${twiturl.toString()}`.replace(/[\t\n]/g, ``)]
10860
10734
  ]);
10861
10735
  if (g_presetObj.resultVals !== undefined) {
10862
- Object.keys(g_presetObj.resultVals).forEach(key => {
10863
- tweetResultTmp = tweetResultTmp.split(`[${key}]`).join(g_resultObj[g_presetObj.resultVals[key]]);
10864
- });
10736
+ Object.keys(g_presetObj.resultVals).forEach(key =>
10737
+ tweetResultTmp = tweetResultTmp.split(`[${key}]`).join(g_resultObj[g_presetObj.resultVals[key]]));
10865
10738
  }
10866
10739
  const resultText = `${unEscapeHtml(tweetResultTmp)}`;
10867
10740
  const tweetResult = `https://twitter.com/intent/tweet?text=${encodeURIComponent(resultText)}`;
@@ -10883,9 +10756,8 @@ const resultInit = _ => {
10883
10756
  resetCommonBtn(`btnBack`, g_lblNameObj.b_back, g_lblPosObj.btnRsBack, titleInit, g_cssObj.button_Back),
10884
10757
 
10885
10758
  // リザルトデータをクリップボードへコピー
10886
- createCss2Button(`btnCopy`, g_lblNameObj.b_copy, _ => {
10887
- copyTextToClipboard(resultText, g_msgInfoObj.I_0001);
10888
- }, g_lblPosObj.btnRsCopy, g_cssObj.button_Setting),
10759
+ createCss2Button(`btnCopy`, g_lblNameObj.b_copy, _ => copyTextToClipboard(resultText, g_msgInfoObj.I_0001),
10760
+ g_lblPosObj.btnRsCopy, g_cssObj.button_Setting),
10889
10761
 
10890
10762
  // リザルトデータをTwitterへ転送
10891
10763
  createCss2Button(`btnTweet`, g_lblNameObj.b_tweet, _ => true, Object.assign(g_lblPosObj.btnRsTweet, {
@@ -10950,7 +10822,7 @@ const resultInit = _ => {
10950
10822
  g_scoreObj.resultFrameNum++;
10951
10823
  g_scoreObj.backResultFrameNum++;
10952
10824
  g_scoreObj.maskResultFrameNum++;
10953
- g_timeoutEvtResultId = setTimeout(_ => flowResultTimeline(), 1000 / g_fps - buffTime);
10825
+ g_timeoutEvtResultId = setTimeout(flowResultTimeline, 1000 / g_fps - buffTime);
10954
10826
  };
10955
10827
  flowResultTimeline();
10956
10828