@woosh/meep-engine 2.115.0 → 2.116.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/build/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +204 -177
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +204 -177
- package/editor/view/ecs/HierarchicalEntityListView.js +2 -2
- package/package.json +1 -1
- package/src/core/collection/array/{compareArrays.d.ts → array_compare.d.ts} +2 -2
- package/src/core/collection/array/array_compare.d.ts.map +1 -0
- package/src/core/collection/array/{compareArrays.js → array_compare.js} +5 -1
- package/src/core/collection/array/{arrayIndexByEquality.d.ts → array_index_by_equality.d.ts} +2 -2
- package/src/core/collection/array/array_index_by_equality.d.ts.map +1 -0
- package/src/core/collection/array/{arrayIndexByEquality.js → array_index_by_equality.js} +1 -1
- package/src/core/collection/array/array_pick_best_element.d.ts.map +1 -0
- package/src/core/collection/array/{arrayPickBestElement.js → array_pick_best_element.js} +2 -2
- package/src/core/collection/array/array_pick_best_elements.d.ts +8 -0
- package/src/core/collection/array/array_pick_best_elements.d.ts.map +1 -0
- package/src/core/collection/array/{arrayPickBestElements.js → array_pick_best_elements.js} +1 -1
- package/src/core/collection/array/array_replace_all.d.ts +2 -1
- package/src/core/collection/array/array_replace_all.d.ts.map +1 -1
- package/src/core/collection/array/array_replace_all.js +3 -0
- package/src/core/collection/array/{arraySetDiff.d.ts → array_set_diff.d.ts} +3 -3
- package/src/core/collection/array/array_set_diff.d.ts.map +1 -0
- package/src/core/collection/array/{arraySetDiff.js → array_set_diff.js} +4 -4
- package/src/core/collection/array/{arraySetSortingDiff.d.ts → array_set_diff_sorting.d.ts} +2 -2
- package/src/core/collection/array/array_set_diff_sorting.d.ts.map +1 -0
- package/src/core/collection/array/{arraySetSortingDiff.js → array_set_diff_sorting.js} +1 -1
- package/src/core/collection/list/FilteredListProjection.d.ts.map +1 -1
- package/src/core/collection/list/FilteredListProjection.js +2 -2
- package/src/core/collection/list/List.d.ts.map +1 -1
- package/src/core/collection/list/List.js +8 -11
- package/src/core/collection/set/ArraySet.d.ts.map +1 -1
- package/src/core/collection/set/ArraySet.js +11 -1
- package/src/core/geom/3d/topology/expandConnectivityByLocality.js +2 -2
- package/src/core/math/physics/brdf/brdf_burley.d.ts.map +1 -1
- package/src/core/math/physics/brdf/brdf_burley.js +3 -14
- package/src/core/math/physics/bsdf/bsdf_schlick.js +1 -1
- package/src/core/math/physics/pdf/pdf_normal.d.ts +8 -0
- package/src/core/math/physics/pdf/pdf_normal.d.ts.map +1 -0
- package/src/core/math/physics/pdf/pdf_normal.js +11 -0
- package/src/core/math/physics/reflectivity_to_ior.d.ts.map +1 -1
- package/src/core/math/physics/reflectivity_to_ior.js +3 -1
- package/src/core/model/object/compareValues.js +3 -3
- package/src/core/primitives/strings/computeStringHash.d.ts +9 -1
- package/src/core/primitives/strings/computeStringHash.d.ts.map +1 -1
- package/src/core/primitives/strings/computeStringHash.js +10 -5
- package/src/engine/ecs/EntityComponentDataset.js +3 -3
- package/src/engine/graphics/ecs/mesh/SkeletonUtils.js +2 -2
- package/src/engine/graphics/sh3/gi/material/common.glsl +3 -2
- package/src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.js +4 -3
- package/src/engine/graphics/sh3/lpv/build_probes_for_scene.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/build_probes_for_scene.js +6 -3
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +16 -12
- package/src/engine/graphics/shaders/DenoiseShader.d.ts.map +1 -1
- package/src/engine/graphics/shaders/DenoiseShader.js +3 -12
- package/src/engine/input/ecs/components/InputBinding.d.ts.map +1 -1
- package/src/engine/input/ecs/components/InputBinding.js +3 -2
- package/src/engine/input/ecs/components/InputController.d.ts.map +1 -1
- package/src/engine/input/ecs/components/InputController.js +18 -1
- package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -9
- package/src/engine/platform/WebEnginePlatform.d.ts.map +1 -1
- package/src/engine/platform/WebEnginePlatform.js +4 -4
- package/src/engine/save/GameStateLoader.js +2 -2
- package/src/engine/ui/cursor/CursorCoalescence.d.ts.map +1 -1
- package/src/engine/ui/cursor/CursorCoalescence.js +2 -2
- package/src/view/elements/radial/RadialMenu.js +2 -2
- package/src/core/collection/array/arrayIndexByEquality.d.ts.map +0 -1
- package/src/core/collection/array/arrayPickBestElement.d.ts.map +0 -1
- package/src/core/collection/array/arrayPickBestElements.d.ts +0 -8
- package/src/core/collection/array/arrayPickBestElements.d.ts.map +0 -1
- package/src/core/collection/array/arraySetDiff.d.ts.map +0 -1
- package/src/core/collection/array/arraySetSortingDiff.d.ts.map +0 -1
- package/src/core/collection/array/compareArrays.d.ts.map +0 -1
- /package/src/core/collection/array/{arrayPickBestElement.d.ts → array_pick_best_element.d.ts} +0 -0
package/build/meep.cjs
CHANGED
|
@@ -50990,9 +50990,11 @@ class Vector4 {
|
|
|
50990
50990
|
/**
|
|
50991
50991
|
*
|
|
50992
50992
|
* @param {string|null|undefined} string
|
|
50993
|
+
* @param {number} [start]
|
|
50994
|
+
* @param {number} [length] how many characters to hash, defaults to full string length
|
|
50993
50995
|
* @returns {number}
|
|
50994
50996
|
*/
|
|
50995
|
-
function computeStringHash(string) {
|
|
50997
|
+
function computeStringHash(string, start, length) {
|
|
50996
50998
|
if (string === null) {
|
|
50997
50999
|
return 0;
|
|
50998
51000
|
}
|
|
@@ -51001,11 +51003,14 @@ function computeStringHash(string) {
|
|
|
51001
51003
|
return 1;
|
|
51002
51004
|
}
|
|
51003
51005
|
|
|
51004
|
-
|
|
51006
|
+
let _start = start ?? 0;
|
|
51007
|
+
let _length = length ?? string.length - _start;
|
|
51005
51008
|
|
|
51006
|
-
let hash =
|
|
51009
|
+
let hash = _length;
|
|
51007
51010
|
|
|
51008
|
-
|
|
51011
|
+
const end = _start + _length;
|
|
51012
|
+
|
|
51013
|
+
for (let i = _start; i < end; i++) {
|
|
51009
51014
|
const code_point = string.charCodeAt(i);
|
|
51010
51015
|
|
|
51011
51016
|
/*
|
|
@@ -59532,6 +59537,26 @@ const AmbientOcclusionShader = function () {
|
|
|
59532
59537
|
}
|
|
59533
59538
|
};
|
|
59534
59539
|
|
|
59540
|
+
/**
|
|
59541
|
+
*
|
|
59542
|
+
* @param {number} sigma distance from mean
|
|
59543
|
+
* @param {number} v Variance
|
|
59544
|
+
* @returns {number}
|
|
59545
|
+
*/
|
|
59546
|
+
function gaussian$1(sigma, v) {
|
|
59547
|
+
return Math.exp(-(v * v) / (2 * sigma * sigma));
|
|
59548
|
+
}
|
|
59549
|
+
|
|
59550
|
+
/**
|
|
59551
|
+
* Normal Probability Distribution Function
|
|
59552
|
+
* @param {number} x
|
|
59553
|
+
* @param {number} sigma
|
|
59554
|
+
* @return {number}
|
|
59555
|
+
*/
|
|
59556
|
+
function pdf_normal(x, sigma) {
|
|
59557
|
+
return 0.39894 * gaussian$1(sigma, x) / sigma;
|
|
59558
|
+
}
|
|
59559
|
+
|
|
59535
59560
|
const KERNEL_SIZE = 15;
|
|
59536
59561
|
|
|
59537
59562
|
const fragment$1 = `
|
|
@@ -59591,16 +59616,6 @@ void main(void) {
|
|
|
59591
59616
|
}
|
|
59592
59617
|
`;
|
|
59593
59618
|
|
|
59594
|
-
/**
|
|
59595
|
-
* Normal Probability Distribution Function
|
|
59596
|
-
* @param {number} x
|
|
59597
|
-
* @param {number} sigma
|
|
59598
|
-
* @return {number}
|
|
59599
|
-
*/
|
|
59600
|
-
function normpdf(x, sigma) {
|
|
59601
|
-
return 0.39894 * Math.exp(-0.5 * x * x / (sigma * sigma)) / sigma;
|
|
59602
|
-
}
|
|
59603
|
-
|
|
59604
59619
|
/**
|
|
59605
59620
|
*
|
|
59606
59621
|
* @param {number} sigma
|
|
@@ -59609,13 +59624,13 @@ function normpdf(x, sigma) {
|
|
|
59609
59624
|
*/
|
|
59610
59625
|
function DenoiseShader(sigma = 10, filterSmoothness = 0.2) {
|
|
59611
59626
|
// compute zNorm
|
|
59612
|
-
const zNorm = 1 /
|
|
59627
|
+
const zNorm = 1 / pdf_normal(0, filterSmoothness);
|
|
59613
59628
|
|
|
59614
59629
|
// build kernel
|
|
59615
59630
|
const kernel = new Float32Array(KERNEL_SIZE);
|
|
59616
59631
|
const kSize = Math.floor((KERNEL_SIZE - 1) / 2);
|
|
59617
59632
|
for (let i = 0; i <= kSize; i++) {
|
|
59618
|
-
const v =
|
|
59633
|
+
const v = pdf_normal(i, sigma);
|
|
59619
59634
|
|
|
59620
59635
|
kernel[kSize + i] = v;
|
|
59621
59636
|
kernel[kSize - i] = v;
|
|
@@ -61409,7 +61424,7 @@ function objectsEqual(a, b) {
|
|
|
61409
61424
|
* @param {function(a:T,b:T):boolean} equals
|
|
61410
61425
|
* @returns {number} index of first match or -1 if no matches found
|
|
61411
61426
|
*/
|
|
61412
|
-
function
|
|
61427
|
+
function array_index_by_equality(array, element, equals) {
|
|
61413
61428
|
const n = array.length;
|
|
61414
61429
|
|
|
61415
61430
|
for (let i = 0; i < n; i++) {
|
|
@@ -61425,14 +61440,14 @@ function arrayIndexByEquality(array, element, equals) {
|
|
|
61425
61440
|
|
|
61426
61441
|
/**
|
|
61427
61442
|
* Compute a diff between two arrays, result is a 3 way split between common items, unique items in `a` array and unique items in `b` array
|
|
61428
|
-
* @see prefer to use {@link
|
|
61443
|
+
* @see prefer to use {@link array_set_diff_sorting}, as it's much faster, especially for large sets
|
|
61429
61444
|
* @template T
|
|
61430
61445
|
* @param {T[]} a
|
|
61431
61446
|
* @param {T[]} b
|
|
61432
61447
|
* @param {function(a:T,b:T):boolean} [equals] method to determine equality between two elements
|
|
61433
61448
|
* @returns {{uniqueA:T[], uniqueB:T[], common:T[]}}
|
|
61434
61449
|
*/
|
|
61435
|
-
function
|
|
61450
|
+
function array_set_diff(a, b, equals = strictEquals) {
|
|
61436
61451
|
|
|
61437
61452
|
const uniqueA = a.slice();
|
|
61438
61453
|
const uniqueB = b.slice();
|
|
@@ -61444,7 +61459,7 @@ function arraySetDiff(a, b, equals = strictEquals) {
|
|
|
61444
61459
|
for (let i = 0; i < a_length; i++) {
|
|
61445
61460
|
const elA = uniqueA[i];
|
|
61446
61461
|
|
|
61447
|
-
const j =
|
|
61462
|
+
const j = array_index_by_equality(uniqueB, elA, equals);
|
|
61448
61463
|
|
|
61449
61464
|
if (j !== -1) {
|
|
61450
61465
|
// common element found
|
|
@@ -61503,8 +61518,7 @@ class List {
|
|
|
61503
61518
|
data = []
|
|
61504
61519
|
|
|
61505
61520
|
/**
|
|
61506
|
-
* @param {[]} [array]
|
|
61507
|
-
* @constructor
|
|
61521
|
+
* @param {T[]} [array]
|
|
61508
61522
|
*/
|
|
61509
61523
|
constructor(array) {
|
|
61510
61524
|
|
|
@@ -61669,7 +61683,7 @@ class List {
|
|
|
61669
61683
|
|
|
61670
61684
|
const data = this.data;
|
|
61671
61685
|
|
|
61672
|
-
const diff =
|
|
61686
|
+
const diff = array_set_diff(data, new_data, objectsEqual);
|
|
61673
61687
|
|
|
61674
61688
|
//resolve diff
|
|
61675
61689
|
const removals = diff.uniqueA;
|
|
@@ -61746,12 +61760,10 @@ class List {
|
|
|
61746
61760
|
* @param {Array.<T>} elements
|
|
61747
61761
|
*/
|
|
61748
61762
|
addAllUnique(elements) {
|
|
61749
|
-
const
|
|
61750
|
-
|
|
61751
|
-
const length = data.length;
|
|
61763
|
+
const length = elements.length;
|
|
61752
61764
|
|
|
61753
61765
|
for (let i = 0; i < length; i++) {
|
|
61754
|
-
this.addUnique(
|
|
61766
|
+
this.addUnique(elements[i]);
|
|
61755
61767
|
}
|
|
61756
61768
|
}
|
|
61757
61769
|
|
|
@@ -61861,7 +61873,7 @@ class List {
|
|
|
61861
61873
|
/**
|
|
61862
61874
|
*
|
|
61863
61875
|
* @param {function(a:T, b:T):number} [compare_function]
|
|
61864
|
-
* @returns {
|
|
61876
|
+
* @returns {this}
|
|
61865
61877
|
*/
|
|
61866
61878
|
sort(compare_function) {
|
|
61867
61879
|
Array.prototype.sort.call(this.data, compare_function);
|
|
@@ -62188,7 +62200,7 @@ class List {
|
|
|
62188
62200
|
for (let i = 0; i < nThisItems; i++) {
|
|
62189
62201
|
const a = thisItems[i];
|
|
62190
62202
|
|
|
62191
|
-
const index =
|
|
62203
|
+
const index = array_index_by_equality(otherItems, a, invokeObjectEquals);
|
|
62192
62204
|
|
|
62193
62205
|
if (index !== -1) {
|
|
62194
62206
|
newData[index] = a;
|
|
@@ -94309,7 +94321,7 @@ class EntityComponentDataset {
|
|
|
94309
94321
|
|
|
94310
94322
|
const newComponentTypeCount = map.length;
|
|
94311
94323
|
|
|
94312
|
-
const diff =
|
|
94324
|
+
const diff = array_set_diff(map, this.componentTypeMap);
|
|
94313
94325
|
|
|
94314
94326
|
const typesToAdd = diff.uniqueA;
|
|
94315
94327
|
const typesToRemove = diff.uniqueB;
|
|
@@ -94527,7 +94539,7 @@ class EntityComponentDataset {
|
|
|
94527
94539
|
* @returns {boolean} false if no new classes were added, true if at least one new class was added
|
|
94528
94540
|
*/
|
|
94529
94541
|
registerManyComponentTypes(types) {
|
|
94530
|
-
const diff =
|
|
94542
|
+
const diff = array_set_diff(types, this.componentTypeMap);
|
|
94531
94543
|
|
|
94532
94544
|
if (diff.uniqueA.length === 0) {
|
|
94533
94545
|
// all classes area already registered
|
|
@@ -105505,7 +105517,7 @@ class InputBinding {
|
|
|
105505
105517
|
class InputController {
|
|
105506
105518
|
/**
|
|
105507
105519
|
*
|
|
105508
|
-
* @param {Array} bindings
|
|
105520
|
+
* @param {Array} [bindings]
|
|
105509
105521
|
* @constructor
|
|
105510
105522
|
*/
|
|
105511
105523
|
constructor(bindings = []) {
|
|
@@ -105521,6 +105533,21 @@ class InputController {
|
|
|
105521
105533
|
};
|
|
105522
105534
|
}
|
|
105523
105535
|
|
|
105536
|
+
/**
|
|
105537
|
+
*
|
|
105538
|
+
* @param {string} path
|
|
105539
|
+
* @param {function} action
|
|
105540
|
+
* @returns {InputBinding}
|
|
105541
|
+
*/
|
|
105542
|
+
bind(path, action) {
|
|
105543
|
+
|
|
105544
|
+
const binding = new InputBinding({ path, listener: action });
|
|
105545
|
+
|
|
105546
|
+
this.mapping.add(binding);
|
|
105547
|
+
|
|
105548
|
+
return binding;
|
|
105549
|
+
}
|
|
105550
|
+
|
|
105524
105551
|
/**
|
|
105525
105552
|
*
|
|
105526
105553
|
* @param {Array} bindings
|
|
@@ -114994,19 +115021,19 @@ class KeyboardCameraController {
|
|
|
114994
115021
|
function registerToggle(keys, object, propertyName) {
|
|
114995
115022
|
keys.forEach((keyName) => {
|
|
114996
115023
|
|
|
114997
|
-
inputController.
|
|
114998
|
-
|
|
114999
|
-
|
|
115024
|
+
inputController.bind(
|
|
115025
|
+
"keyboard/keys/" + keyName + "/down",
|
|
115026
|
+
() => {
|
|
115000
115027
|
object[propertyName] = true;
|
|
115001
115028
|
|
|
115002
115029
|
//send interaction event
|
|
115003
115030
|
ecd.sendEvent(cameraController.entity, 'user-input');
|
|
115004
115031
|
}
|
|
115005
|
-
|
|
115006
|
-
inputController.
|
|
115007
|
-
|
|
115008
|
-
|
|
115009
|
-
|
|
115032
|
+
);
|
|
115033
|
+
inputController.bind(
|
|
115034
|
+
"keyboard/keys/" + keyName + "/up",
|
|
115035
|
+
() => object[propertyName] = false
|
|
115036
|
+
);
|
|
115010
115037
|
});
|
|
115011
115038
|
}
|
|
115012
115039
|
|
|
@@ -115038,7 +115065,7 @@ class KeyboardCameraController {
|
|
|
115038
115065
|
return;
|
|
115039
115066
|
}
|
|
115040
115067
|
|
|
115041
|
-
|
|
115068
|
+
const displacement = cameraPanSpeed.clone().multiplyScalar(keyboardPanSpeed * timeDelta);
|
|
115042
115069
|
|
|
115043
115070
|
const camera_transform = ecd.getComponent(cameraController.entity, Transform);
|
|
115044
115071
|
|
|
@@ -115489,43 +115516,138 @@ function getURLHash() {
|
|
|
115489
115516
|
return result;
|
|
115490
115517
|
}
|
|
115491
115518
|
|
|
115492
|
-
|
|
115493
|
-
|
|
115494
|
-
|
|
115495
|
-
|
|
115496
|
-
|
|
115497
|
-
|
|
115519
|
+
/**
|
|
115520
|
+
* Picks element with highest score from the array using supplied scoring function.
|
|
115521
|
+
* If multiple elements with the same highest score exist, the result will be first such encountered element
|
|
115522
|
+
* @template T
|
|
115523
|
+
* @param {T[]} array
|
|
115524
|
+
* @param {function(el:T, index:number):number} scoreFunction
|
|
115525
|
+
* @returns {T|undefined}
|
|
115526
|
+
*/
|
|
115527
|
+
function array_pick_best_element(array, scoreFunction) {
|
|
115528
|
+
|
|
115529
|
+
let bestElement;
|
|
115530
|
+
let bestScore;
|
|
115531
|
+
|
|
115532
|
+
const size = array.length;
|
|
115533
|
+
|
|
115534
|
+
if (size === 0) {
|
|
115535
|
+
return undefined;
|
|
115498
115536
|
}
|
|
115499
115537
|
|
|
115500
|
-
|
|
115501
|
-
|
|
115502
|
-
|
|
115503
|
-
|
|
115504
|
-
|
|
115538
|
+
bestElement = array[0];
|
|
115539
|
+
|
|
115540
|
+
bestScore = scoreFunction(bestElement, 0);
|
|
115541
|
+
|
|
115542
|
+
for (let i = 1; i < size; i++) {
|
|
115543
|
+
const el = array[i];
|
|
115544
|
+
|
|
115545
|
+
// compute score
|
|
115546
|
+
const score = scoreFunction(el, i);
|
|
115547
|
+
|
|
115548
|
+
if (score > bestScore) {
|
|
115549
|
+
bestScore = score;
|
|
115550
|
+
bestElement = el;
|
|
115551
|
+
}
|
|
115552
|
+
}
|
|
115553
|
+
|
|
115554
|
+
return bestElement;
|
|
115555
|
+
}
|
|
115556
|
+
|
|
115557
|
+
/**
|
|
115558
|
+
* Base class for implementing achievement system API connectors
|
|
115559
|
+
*/
|
|
115560
|
+
class AchievementGateway {
|
|
115561
|
+
constructor() {
|
|
115562
|
+
|
|
115505
115563
|
}
|
|
115506
115564
|
|
|
115507
115565
|
/**
|
|
115508
|
-
*
|
|
115509
|
-
* @returns {
|
|
115566
|
+
* Retrieve list of unlocked achievements
|
|
115567
|
+
* @returns {Promise<String[]>} IDs of unlocked achievements
|
|
115510
115568
|
*/
|
|
115511
|
-
|
|
115569
|
+
getUnlocked() {
|
|
115570
|
+
//needs to be overridden in subclass
|
|
115512
115571
|
throw new Error('Not implemented');
|
|
115513
115572
|
}
|
|
115514
115573
|
|
|
115515
115574
|
/**
|
|
115575
|
+
* Unlock an achievements by ID
|
|
115576
|
+
* @param {String} id
|
|
115516
115577
|
* @returns {Promise}
|
|
115517
115578
|
*/
|
|
115518
|
-
|
|
115519
|
-
|
|
115579
|
+
unlock(id) {
|
|
115580
|
+
//needs to be overridden in subclass
|
|
115581
|
+
throw new Error('Not implemented');
|
|
115520
115582
|
}
|
|
115521
|
-
|
|
115583
|
+
}
|
|
115584
|
+
|
|
115585
|
+
class StorageAchievementGateway extends AchievementGateway {
|
|
115522
115586
|
/**
|
|
115523
|
-
*
|
|
115587
|
+
*
|
|
115588
|
+
* @param {Storage} storage
|
|
115589
|
+
* @param {String} [key]
|
|
115524
115590
|
*/
|
|
115525
|
-
|
|
115526
|
-
|
|
115591
|
+
constructor(storage, key = "achievements") {
|
|
115592
|
+
super();
|
|
115593
|
+
|
|
115594
|
+
this.storage = storage;
|
|
115595
|
+
|
|
115596
|
+
this.key = key;
|
|
115597
|
+
|
|
115598
|
+
this.last = Promise.resolve();
|
|
115527
115599
|
}
|
|
115528
115600
|
|
|
115601
|
+
getUnlocked() {
|
|
115602
|
+
return new Promise((resolve, reject) => {
|
|
115603
|
+
this.storage.load(this.key, (list) => {
|
|
115604
|
+
|
|
115605
|
+
if (list === undefined) {
|
|
115606
|
+
resolve([]);
|
|
115607
|
+
} else {
|
|
115608
|
+
resolve(list);
|
|
115609
|
+
}
|
|
115610
|
+
|
|
115611
|
+
}, reject, noop);
|
|
115612
|
+
});
|
|
115613
|
+
}
|
|
115614
|
+
|
|
115615
|
+
unlock(id) {
|
|
115616
|
+
const storage = this.storage;
|
|
115617
|
+
|
|
115618
|
+
const promise = this.last.finally(() => {
|
|
115619
|
+
return new Promise((resolve, reject) => {
|
|
115620
|
+
//read list of unlocked achievements
|
|
115621
|
+
storage.load(this.key, list => {
|
|
115622
|
+
|
|
115623
|
+
let unlocked;
|
|
115624
|
+
if (list !== undefined) {
|
|
115625
|
+
if (list.includes(id)) {
|
|
115626
|
+
//achievement is already unlocked
|
|
115627
|
+
resolve();
|
|
115628
|
+
return;
|
|
115629
|
+
}
|
|
115630
|
+
|
|
115631
|
+
unlocked = list.slice();
|
|
115632
|
+
|
|
115633
|
+
} else {
|
|
115634
|
+
unlocked = [];
|
|
115635
|
+
}
|
|
115636
|
+
|
|
115637
|
+
//modify unlocked achievements
|
|
115638
|
+
unlocked.push(id);
|
|
115639
|
+
|
|
115640
|
+
//write back
|
|
115641
|
+
storage.store(this.key, unlocked, resolve, reject, noop);
|
|
115642
|
+
}, reject, noop);
|
|
115643
|
+
});
|
|
115644
|
+
}
|
|
115645
|
+
);
|
|
115646
|
+
|
|
115647
|
+
this.last = promise;
|
|
115648
|
+
|
|
115649
|
+
return promise;
|
|
115650
|
+
}
|
|
115529
115651
|
}
|
|
115530
115652
|
|
|
115531
115653
|
class Storage {
|
|
@@ -115799,138 +115921,43 @@ class IndexedDBStorage extends Storage {
|
|
|
115799
115921
|
}
|
|
115800
115922
|
}
|
|
115801
115923
|
|
|
115802
|
-
|
|
115803
|
-
* Base class for implementing achievement system API connectors
|
|
115804
|
-
*/
|
|
115805
|
-
class AchievementGateway {
|
|
115806
|
-
constructor() {
|
|
115807
|
-
|
|
115808
|
-
}
|
|
115809
|
-
|
|
115924
|
+
class EnginePlatform {
|
|
115810
115925
|
/**
|
|
115811
|
-
*
|
|
115812
|
-
* @returns {Promise<String[]>} IDs of unlocked achievements
|
|
115926
|
+
* @returns {Storage}
|
|
115813
115927
|
*/
|
|
115814
|
-
|
|
115815
|
-
//needs to be overridden in subclass
|
|
115928
|
+
getStorage() {
|
|
115816
115929
|
throw new Error('Not implemented');
|
|
115817
115930
|
}
|
|
115818
115931
|
|
|
115819
115932
|
/**
|
|
115820
|
-
*
|
|
115821
|
-
* @param {String} id
|
|
115822
|
-
* @returns {Promise}
|
|
115933
|
+
* @returns {AchievementGateway}
|
|
115823
115934
|
*/
|
|
115824
|
-
|
|
115825
|
-
//needs to be overridden in subclass
|
|
115935
|
+
getAchievementGateway() {
|
|
115826
115936
|
throw new Error('Not implemented');
|
|
115827
115937
|
}
|
|
115828
|
-
|
|
115829
|
-
|
|
115830
|
-
class StorageAchievementGateway extends AchievementGateway {
|
|
115938
|
+
|
|
115831
115939
|
/**
|
|
115832
|
-
*
|
|
115833
|
-
* @
|
|
115834
|
-
* @param {String} [key]
|
|
115940
|
+
* @param {string[]} options
|
|
115941
|
+
* @returns {string}
|
|
115835
115942
|
*/
|
|
115836
|
-
|
|
115837
|
-
|
|
115838
|
-
|
|
115839
|
-
this.storage = storage;
|
|
115840
|
-
|
|
115841
|
-
this.key = key;
|
|
115842
|
-
|
|
115843
|
-
this.last = Promise.resolve();
|
|
115844
|
-
}
|
|
115845
|
-
|
|
115846
|
-
getUnlocked() {
|
|
115847
|
-
return new Promise((resolve, reject) => {
|
|
115848
|
-
this.storage.load(this.key, (list) => {
|
|
115849
|
-
|
|
115850
|
-
if (list === undefined) {
|
|
115851
|
-
resolve([]);
|
|
115852
|
-
} else {
|
|
115853
|
-
resolve(list);
|
|
115854
|
-
}
|
|
115855
|
-
|
|
115856
|
-
}, reject, noop);
|
|
115857
|
-
});
|
|
115858
|
-
}
|
|
115859
|
-
|
|
115860
|
-
unlock(id) {
|
|
115861
|
-
const storage = this.storage;
|
|
115862
|
-
|
|
115863
|
-
const promise = this.last.finally(() => {
|
|
115864
|
-
return new Promise((resolve, reject) => {
|
|
115865
|
-
//read list of unlocked achievements
|
|
115866
|
-
storage.load(this.key, list => {
|
|
115867
|
-
|
|
115868
|
-
let unlocked;
|
|
115869
|
-
if (list !== undefined) {
|
|
115870
|
-
if (list.includes(id)) {
|
|
115871
|
-
//achievement is already unlocked
|
|
115872
|
-
resolve();
|
|
115873
|
-
return;
|
|
115874
|
-
}
|
|
115875
|
-
|
|
115876
|
-
unlocked = list.slice();
|
|
115877
|
-
|
|
115878
|
-
} else {
|
|
115879
|
-
unlocked = [];
|
|
115880
|
-
}
|
|
115881
|
-
|
|
115882
|
-
//modify unlocked achievements
|
|
115883
|
-
unlocked.push(id);
|
|
115884
|
-
|
|
115885
|
-
//write back
|
|
115886
|
-
storage.store(this.key, unlocked, resolve, reject, noop);
|
|
115887
|
-
}, reject, noop);
|
|
115888
|
-
});
|
|
115889
|
-
}
|
|
115890
|
-
);
|
|
115891
|
-
|
|
115892
|
-
this.last = promise;
|
|
115893
|
-
|
|
115894
|
-
return promise;
|
|
115943
|
+
pickDefaultLocale(options) {
|
|
115944
|
+
throw new Error('Not implemented');
|
|
115895
115945
|
}
|
|
115896
|
-
}
|
|
115897
|
-
|
|
115898
|
-
/**
|
|
115899
|
-
* Picks element with highest score from the array using supplied scoring function.
|
|
115900
|
-
* If multiple elements with the same highest score exist, the result will be first such encountered element
|
|
115901
|
-
* @template T
|
|
115902
|
-
* @param {T[]} array
|
|
115903
|
-
* @param {function(el:T, index:number):number} scoreFunction
|
|
115904
|
-
* @returns {T|undefined}
|
|
115905
|
-
*/
|
|
115906
|
-
function arrayPickBestElement(array, scoreFunction) {
|
|
115907
|
-
|
|
115908
|
-
let bestElement;
|
|
115909
|
-
let bestScore;
|
|
115910
115946
|
|
|
115911
|
-
|
|
115912
|
-
|
|
115913
|
-
|
|
115914
|
-
|
|
115947
|
+
/**
|
|
115948
|
+
* @returns {Promise}
|
|
115949
|
+
*/
|
|
115950
|
+
startup() {
|
|
115951
|
+
return Promise.resolve();
|
|
115915
115952
|
}
|
|
115916
115953
|
|
|
115917
|
-
|
|
115918
|
-
|
|
115919
|
-
|
|
115920
|
-
|
|
115921
|
-
|
|
115922
|
-
const el = array[i];
|
|
115923
|
-
|
|
115924
|
-
// compute score
|
|
115925
|
-
const score = scoreFunction(el, i);
|
|
115926
|
-
|
|
115927
|
-
if (score > bestScore) {
|
|
115928
|
-
bestScore = score;
|
|
115929
|
-
bestElement = el;
|
|
115930
|
-
}
|
|
115954
|
+
/**
|
|
115955
|
+
* @returns {Promise}
|
|
115956
|
+
*/
|
|
115957
|
+
shutdown() {
|
|
115958
|
+
return Promise.resolve();
|
|
115931
115959
|
}
|
|
115932
115960
|
|
|
115933
|
-
return bestElement;
|
|
115934
115961
|
}
|
|
115935
115962
|
|
|
115936
115963
|
class WebEnginePlatform extends EnginePlatform {
|
|
@@ -116005,7 +116032,7 @@ class WebEnginePlatform extends EnginePlatform {
|
|
|
116005
116032
|
};
|
|
116006
116033
|
});
|
|
116007
116034
|
|
|
116008
|
-
const best =
|
|
116035
|
+
const best = array_pick_best_element(scoredKeys, o => o.score);
|
|
116009
116036
|
|
|
116010
116037
|
if (best.score === 0) {
|
|
116011
116038
|
return 'en-gb';
|