@routevn/creator-model 1.7.3 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/model.js +519 -5
package/package.json
CHANGED
package/src/model.js
CHANGED
|
@@ -392,7 +392,7 @@ const LAYOUT_ELEMENT_BASE_TYPES = [
|
|
|
392
392
|
"container-ref-confirm-dialog-ok",
|
|
393
393
|
"container-ref-confirm-dialog-cancel",
|
|
394
394
|
];
|
|
395
|
-
export const SCHEMA_VERSION =
|
|
395
|
+
export const SCHEMA_VERSION = 8;
|
|
396
396
|
const LAYOUT_CONTAINER_ELEMENT_TYPES = [
|
|
397
397
|
"folder",
|
|
398
398
|
"container",
|
|
@@ -404,6 +404,18 @@ const LAYOUT_CONTAINER_ELEMENT_TYPES = [
|
|
|
404
404
|
"container-ref-confirm-dialog-ok",
|
|
405
405
|
"container-ref-confirm-dialog-cancel",
|
|
406
406
|
];
|
|
407
|
+
const LAYOUT_TEXT_CONTENT_ELEMENT_TYPES = [
|
|
408
|
+
"text",
|
|
409
|
+
"text-revealing",
|
|
410
|
+
"text-ref-character-name",
|
|
411
|
+
"text-revealing-ref-dialogue-content",
|
|
412
|
+
"text-ref-choice-item-content",
|
|
413
|
+
"text-ref-save-load-slot-date",
|
|
414
|
+
"text-ref-dialogue-line-character-name",
|
|
415
|
+
"text-ref-dialogue-line-content",
|
|
416
|
+
"text-ref-history-line-character-name",
|
|
417
|
+
"text-ref-history-line-content",
|
|
418
|
+
];
|
|
407
419
|
const DOMAIN_ERROR_KIND_BY_NAME = {
|
|
408
420
|
PayloadValidationError: "payload",
|
|
409
421
|
PreconditionValidationError: "precondition",
|
|
@@ -3419,6 +3431,251 @@ const validateLayoutElementBlur = ({ blur, path, errorFactory }) => {
|
|
|
3419
3431
|
}
|
|
3420
3432
|
};
|
|
3421
3433
|
|
|
3434
|
+
const LAYOUT_TEXT_REVEAL_INDICATOR_ELEMENT_TYPES = [
|
|
3435
|
+
"text-revealing",
|
|
3436
|
+
"text-revealing-ref-dialogue-content",
|
|
3437
|
+
];
|
|
3438
|
+
|
|
3439
|
+
const validateLayoutTextRevealIndicatorVisual = ({
|
|
3440
|
+
visual,
|
|
3441
|
+
path,
|
|
3442
|
+
errorFactory,
|
|
3443
|
+
}) => {
|
|
3444
|
+
if (!isPlainObject(visual)) {
|
|
3445
|
+
return invalidFromErrorFactory(
|
|
3446
|
+
errorFactory,
|
|
3447
|
+
`${path} must be an object when provided`,
|
|
3448
|
+
);
|
|
3449
|
+
}
|
|
3450
|
+
|
|
3451
|
+
{
|
|
3452
|
+
const result = validateAllowedKeys({
|
|
3453
|
+
value: visual,
|
|
3454
|
+
allowedKeys: [
|
|
3455
|
+
"kind",
|
|
3456
|
+
"imageId",
|
|
3457
|
+
"resourceId",
|
|
3458
|
+
"animationName",
|
|
3459
|
+
"width",
|
|
3460
|
+
"height",
|
|
3461
|
+
"offsetX",
|
|
3462
|
+
"offsetY",
|
|
3463
|
+
],
|
|
3464
|
+
path,
|
|
3465
|
+
errorFactory,
|
|
3466
|
+
});
|
|
3467
|
+
if (result?.valid === false) {
|
|
3468
|
+
return result;
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
const kind =
|
|
3473
|
+
visual.kind === "spritesheet" ||
|
|
3474
|
+
visual.resourceId !== undefined ||
|
|
3475
|
+
visual.animationName !== undefined
|
|
3476
|
+
? "spritesheet"
|
|
3477
|
+
: "image";
|
|
3478
|
+
|
|
3479
|
+
if (
|
|
3480
|
+
visual.kind !== undefined &&
|
|
3481
|
+
visual.kind !== "image" &&
|
|
3482
|
+
visual.kind !== "spritesheet"
|
|
3483
|
+
) {
|
|
3484
|
+
return invalidFromErrorFactory(
|
|
3485
|
+
errorFactory,
|
|
3486
|
+
`${path}.kind must be 'image' or 'spritesheet' when provided`,
|
|
3487
|
+
);
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
if (kind === "image" && !isNonEmptyString(visual.imageId)) {
|
|
3491
|
+
return invalidFromErrorFactory(
|
|
3492
|
+
errorFactory,
|
|
3493
|
+
`${path}.imageId must be a non-empty string`,
|
|
3494
|
+
);
|
|
3495
|
+
}
|
|
3496
|
+
|
|
3497
|
+
if (kind === "spritesheet") {
|
|
3498
|
+
if (!isNonEmptyString(visual.resourceId)) {
|
|
3499
|
+
return invalidFromErrorFactory(
|
|
3500
|
+
errorFactory,
|
|
3501
|
+
`${path}.resourceId must be a non-empty string`,
|
|
3502
|
+
);
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3505
|
+
if (!isNonEmptyString(visual.animationName)) {
|
|
3506
|
+
return invalidFromErrorFactory(
|
|
3507
|
+
errorFactory,
|
|
3508
|
+
`${path}.animationName must be a non-empty string`,
|
|
3509
|
+
);
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3513
|
+
for (const key of ["width", "height"]) {
|
|
3514
|
+
if (
|
|
3515
|
+
visual[key] !== undefined &&
|
|
3516
|
+
(!isFiniteNumber(visual[key]) || visual[key] <= 0)
|
|
3517
|
+
) {
|
|
3518
|
+
return invalidFromErrorFactory(
|
|
3519
|
+
errorFactory,
|
|
3520
|
+
`${path}.${key} must be a finite number greater than 0 when provided`,
|
|
3521
|
+
);
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
for (const key of ["offsetX", "offsetY"]) {
|
|
3526
|
+
if (visual[key] !== undefined && !isFiniteNumber(visual[key])) {
|
|
3527
|
+
return invalidFromErrorFactory(
|
|
3528
|
+
errorFactory,
|
|
3529
|
+
`${path}.${key} must be a finite number when provided`,
|
|
3530
|
+
);
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
};
|
|
3534
|
+
|
|
3535
|
+
const validateLayoutTextRevealIndicator = ({
|
|
3536
|
+
indicator,
|
|
3537
|
+
path,
|
|
3538
|
+
errorFactory,
|
|
3539
|
+
}) => {
|
|
3540
|
+
if (!isPlainObject(indicator)) {
|
|
3541
|
+
return invalidFromErrorFactory(
|
|
3542
|
+
errorFactory,
|
|
3543
|
+
`${path} must be an object when provided`,
|
|
3544
|
+
);
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
{
|
|
3548
|
+
const result = validateAllowedKeys({
|
|
3549
|
+
value: indicator,
|
|
3550
|
+
allowedKeys: ["revealing", "complete", "offsetX", "offsetY"],
|
|
3551
|
+
path,
|
|
3552
|
+
errorFactory,
|
|
3553
|
+
});
|
|
3554
|
+
if (result?.valid === false) {
|
|
3555
|
+
return result;
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
for (const key of ["revealing", "complete"]) {
|
|
3560
|
+
if (indicator[key] !== undefined) {
|
|
3561
|
+
const result = validateLayoutTextRevealIndicatorVisual({
|
|
3562
|
+
visual: indicator[key],
|
|
3563
|
+
path: `${path}.${key}`,
|
|
3564
|
+
errorFactory,
|
|
3565
|
+
});
|
|
3566
|
+
if (result?.valid === false) {
|
|
3567
|
+
return result;
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
3571
|
+
|
|
3572
|
+
for (const key of ["offsetX", "offsetY"]) {
|
|
3573
|
+
if (indicator[key] !== undefined && !isFiniteNumber(indicator[key])) {
|
|
3574
|
+
return invalidFromErrorFactory(
|
|
3575
|
+
errorFactory,
|
|
3576
|
+
`${path}.${key} must be a finite number when provided`,
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
};
|
|
3581
|
+
|
|
3582
|
+
const validateLayoutTextContent = ({ content, path, errorFactory }) => {
|
|
3583
|
+
if (!Array.isArray(content)) {
|
|
3584
|
+
return invalidFromErrorFactory(
|
|
3585
|
+
errorFactory,
|
|
3586
|
+
`${path} must be an array when provided`,
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3590
|
+
for (let index = 0; index < content.length; index += 1) {
|
|
3591
|
+
const item = content[index];
|
|
3592
|
+
const itemPath = `${path}[${index}]`;
|
|
3593
|
+
|
|
3594
|
+
if (!isPlainObject(item)) {
|
|
3595
|
+
return invalidFromErrorFactory(
|
|
3596
|
+
errorFactory,
|
|
3597
|
+
`${itemPath} must be an object`,
|
|
3598
|
+
);
|
|
3599
|
+
}
|
|
3600
|
+
|
|
3601
|
+
{
|
|
3602
|
+
const result = validateAllowedKeys({
|
|
3603
|
+
value: item,
|
|
3604
|
+
allowedKeys: ["text", "reference"],
|
|
3605
|
+
path: itemPath,
|
|
3606
|
+
errorFactory,
|
|
3607
|
+
});
|
|
3608
|
+
if (result?.valid === false) {
|
|
3609
|
+
return result;
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
const hasText = Object.hasOwn(item, "text");
|
|
3614
|
+
const hasReference = Object.hasOwn(item, "reference");
|
|
3615
|
+
|
|
3616
|
+
if (hasText === hasReference) {
|
|
3617
|
+
return invalidFromErrorFactory(
|
|
3618
|
+
errorFactory,
|
|
3619
|
+
`${itemPath} must include exactly one of text or reference`,
|
|
3620
|
+
);
|
|
3621
|
+
}
|
|
3622
|
+
|
|
3623
|
+
if (hasText) {
|
|
3624
|
+
if (!isString(item.text)) {
|
|
3625
|
+
return invalidFromErrorFactory(
|
|
3626
|
+
errorFactory,
|
|
3627
|
+
`${itemPath}.text must be a string`,
|
|
3628
|
+
);
|
|
3629
|
+
}
|
|
3630
|
+
continue;
|
|
3631
|
+
}
|
|
3632
|
+
|
|
3633
|
+
if (!isPlainObject(item.reference)) {
|
|
3634
|
+
return invalidFromErrorFactory(
|
|
3635
|
+
errorFactory,
|
|
3636
|
+
`${itemPath}.reference must be an object`,
|
|
3637
|
+
);
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
{
|
|
3641
|
+
const result = validateAllowedKeys({
|
|
3642
|
+
value: item.reference,
|
|
3643
|
+
allowedKeys: ["resourceId"],
|
|
3644
|
+
path: `${itemPath}.reference`,
|
|
3645
|
+
errorFactory,
|
|
3646
|
+
});
|
|
3647
|
+
if (result?.valid === false) {
|
|
3648
|
+
return result;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3652
|
+
if (!isNonEmptyString(item.reference.resourceId)) {
|
|
3653
|
+
return invalidFromErrorFactory(
|
|
3654
|
+
errorFactory,
|
|
3655
|
+
`${itemPath}.reference.resourceId must be a non-empty string`,
|
|
3656
|
+
);
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
};
|
|
3660
|
+
|
|
3661
|
+
const getLayoutTextContentReferenceEntries = (content) => {
|
|
3662
|
+
if (!Array.isArray(content)) {
|
|
3663
|
+
return [];
|
|
3664
|
+
}
|
|
3665
|
+
|
|
3666
|
+
const entries = [];
|
|
3667
|
+
for (let index = 0; index < content.length; index += 1) {
|
|
3668
|
+
const resourceId = content[index]?.reference?.resourceId;
|
|
3669
|
+
if (resourceId !== undefined) {
|
|
3670
|
+
entries.push({
|
|
3671
|
+
index,
|
|
3672
|
+
resourceId,
|
|
3673
|
+
});
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
return entries;
|
|
3677
|
+
};
|
|
3678
|
+
|
|
3422
3679
|
const validateLayoutElementData = ({
|
|
3423
3680
|
data,
|
|
3424
3681
|
path,
|
|
@@ -3447,9 +3704,11 @@ const validateLayoutElementData = ({
|
|
|
3447
3704
|
"fill",
|
|
3448
3705
|
"border",
|
|
3449
3706
|
"text",
|
|
3707
|
+
"content",
|
|
3450
3708
|
"textStyle",
|
|
3451
3709
|
"displaySpeed",
|
|
3452
3710
|
"revealEffect",
|
|
3711
|
+
"indicator",
|
|
3453
3712
|
"resourceId",
|
|
3454
3713
|
"animationName",
|
|
3455
3714
|
"imageId",
|
|
@@ -3628,6 +3887,52 @@ const validateLayoutElementData = ({
|
|
|
3628
3887
|
}
|
|
3629
3888
|
}
|
|
3630
3889
|
|
|
3890
|
+
if (data.content !== undefined) {
|
|
3891
|
+
{
|
|
3892
|
+
const result = validateLayoutTextContent({
|
|
3893
|
+
content: data.content,
|
|
3894
|
+
path: `${path}.content`,
|
|
3895
|
+
errorFactory,
|
|
3896
|
+
});
|
|
3897
|
+
if (result?.valid === false) {
|
|
3898
|
+
return result;
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
|
|
3902
|
+
if (
|
|
3903
|
+
data.type !== undefined &&
|
|
3904
|
+
!LAYOUT_TEXT_CONTENT_ELEMENT_TYPES.includes(data.type)
|
|
3905
|
+
) {
|
|
3906
|
+
return invalidFromErrorFactory(
|
|
3907
|
+
errorFactory,
|
|
3908
|
+
`${path}.content can only be provided for text elements`,
|
|
3909
|
+
);
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
if (data.indicator !== undefined) {
|
|
3914
|
+
{
|
|
3915
|
+
const result = validateLayoutTextRevealIndicator({
|
|
3916
|
+
indicator: data.indicator,
|
|
3917
|
+
path: `${path}.indicator`,
|
|
3918
|
+
errorFactory,
|
|
3919
|
+
});
|
|
3920
|
+
if (result?.valid === false) {
|
|
3921
|
+
return result;
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
|
|
3925
|
+
if (
|
|
3926
|
+
data.type !== undefined &&
|
|
3927
|
+
!LAYOUT_TEXT_REVEAL_INDICATOR_ELEMENT_TYPES.includes(data.type)
|
|
3928
|
+
) {
|
|
3929
|
+
return invalidFromErrorFactory(
|
|
3930
|
+
errorFactory,
|
|
3931
|
+
`${path}.indicator can only be provided for text revealing elements`,
|
|
3932
|
+
);
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3631
3936
|
for (const key of [
|
|
3632
3937
|
"text",
|
|
3633
3938
|
"resourceId",
|
|
@@ -4143,9 +4448,11 @@ const validateLayoutElementItems = ({ items, path, errorFactory }) => {
|
|
|
4143
4448
|
"fill",
|
|
4144
4449
|
"border",
|
|
4145
4450
|
"text",
|
|
4451
|
+
"content",
|
|
4146
4452
|
"textStyle",
|
|
4147
4453
|
"displaySpeed",
|
|
4148
4454
|
"revealEffect",
|
|
4455
|
+
"indicator",
|
|
4149
4456
|
"resourceId",
|
|
4150
4457
|
"animationName",
|
|
4151
4458
|
"particleId",
|
|
@@ -7420,15 +7727,16 @@ export const assertInvariants = ({ state }) => {
|
|
|
7420
7727
|
elementId,
|
|
7421
7728
|
targetId,
|
|
7422
7729
|
animationName,
|
|
7730
|
+
fieldPrefix = "",
|
|
7423
7731
|
}) => {
|
|
7424
7732
|
const spritesheet = state.spritesheets?.items?.[targetId];
|
|
7425
7733
|
if (!isPlainObject(spritesheet) || spritesheet.type === "folder") {
|
|
7426
7734
|
return invalidInvariant(
|
|
7427
|
-
`${ownerLabel} element resourceId must reference an existing non-folder spritesheet`,
|
|
7735
|
+
`${ownerLabel} element ${fieldPrefix}resourceId must reference an existing non-folder spritesheet`,
|
|
7428
7736
|
{
|
|
7429
7737
|
[ownerIdField]: ownerId,
|
|
7430
7738
|
elementId,
|
|
7431
|
-
field:
|
|
7739
|
+
field: `${fieldPrefix}resourceId`,
|
|
7432
7740
|
targetId,
|
|
7433
7741
|
},
|
|
7434
7742
|
);
|
|
@@ -7439,11 +7747,11 @@ export const assertInvariants = ({ state }) => {
|
|
|
7439
7747
|
!isPlainObject(spritesheet.animations?.[animationName])
|
|
7440
7748
|
) {
|
|
7441
7749
|
return invalidInvariant(
|
|
7442
|
-
`${ownerLabel} element animationName must reference an existing spritesheet animation`,
|
|
7750
|
+
`${ownerLabel} element ${fieldPrefix}animationName must reference an existing spritesheet animation`,
|
|
7443
7751
|
{
|
|
7444
7752
|
[ownerIdField]: ownerId,
|
|
7445
7753
|
elementId,
|
|
7446
|
-
field:
|
|
7754
|
+
field: `${fieldPrefix}animationName`,
|
|
7447
7755
|
targetId: animationName,
|
|
7448
7756
|
},
|
|
7449
7757
|
);
|
|
@@ -7542,6 +7850,43 @@ export const assertInvariants = ({ state }) => {
|
|
|
7542
7850
|
}
|
|
7543
7851
|
}
|
|
7544
7852
|
|
|
7853
|
+
for (const stateName of ["revealing", "complete"]) {
|
|
7854
|
+
const visual = element.indicator?.[stateName];
|
|
7855
|
+
if (
|
|
7856
|
+
visual?.kind === "spritesheet" ||
|
|
7857
|
+
visual?.resourceId !== undefined ||
|
|
7858
|
+
visual?.animationName !== undefined
|
|
7859
|
+
) {
|
|
7860
|
+
const result = assertSpritesheetAnimationReference({
|
|
7861
|
+
ownerIdField,
|
|
7862
|
+
ownerId,
|
|
7863
|
+
ownerLabel,
|
|
7864
|
+
elementId,
|
|
7865
|
+
targetId: visual.resourceId,
|
|
7866
|
+
animationName: visual.animationName,
|
|
7867
|
+
fieldPrefix: `indicator.${stateName}.`,
|
|
7868
|
+
});
|
|
7869
|
+
if (!result.valid) {
|
|
7870
|
+
return result;
|
|
7871
|
+
}
|
|
7872
|
+
continue;
|
|
7873
|
+
}
|
|
7874
|
+
|
|
7875
|
+
if (visual?.imageId !== undefined) {
|
|
7876
|
+
const result = assertImageReference({
|
|
7877
|
+
ownerIdField,
|
|
7878
|
+
ownerId,
|
|
7879
|
+
ownerLabel,
|
|
7880
|
+
elementId,
|
|
7881
|
+
field: `indicator.${stateName}.imageId`,
|
|
7882
|
+
targetId: visual.imageId,
|
|
7883
|
+
});
|
|
7884
|
+
if (!result.valid) {
|
|
7885
|
+
return result;
|
|
7886
|
+
}
|
|
7887
|
+
}
|
|
7888
|
+
}
|
|
7889
|
+
|
|
7545
7890
|
for (const field of ["hoverSoundId", "clickSoundId"]) {
|
|
7546
7891
|
if (element[field] !== undefined) {
|
|
7547
7892
|
const result = assertSoundReference({
|
|
@@ -7639,6 +7984,23 @@ export const assertInvariants = ({ state }) => {
|
|
|
7639
7984
|
}
|
|
7640
7985
|
}
|
|
7641
7986
|
|
|
7987
|
+
for (const {
|
|
7988
|
+
index,
|
|
7989
|
+
resourceId,
|
|
7990
|
+
} of getLayoutTextContentReferenceEntries(element.content)) {
|
|
7991
|
+
if (!isVariableReferenceTarget(state, resourceId)) {
|
|
7992
|
+
return invalidInvariant(
|
|
7993
|
+
`${ownerLabel} element content.${index}.reference.resourceId must reference an existing non-folder variable`,
|
|
7994
|
+
{
|
|
7995
|
+
[ownerIdField]: ownerId,
|
|
7996
|
+
elementId,
|
|
7997
|
+
field: `content.${index}.reference.resourceId`,
|
|
7998
|
+
targetId: resourceId,
|
|
7999
|
+
},
|
|
8000
|
+
);
|
|
8001
|
+
}
|
|
8002
|
+
}
|
|
8003
|
+
|
|
7642
8004
|
if (element.variableId !== undefined) {
|
|
7643
8005
|
const result = assertVariableReference({
|
|
7644
8006
|
ownerIdField,
|
|
@@ -11383,6 +11745,36 @@ const validateVisualElementReferenceTargets = ({
|
|
|
11383
11745
|
);
|
|
11384
11746
|
}
|
|
11385
11747
|
|
|
11748
|
+
if (
|
|
11749
|
+
data.indicator !== undefined &&
|
|
11750
|
+
!LAYOUT_TEXT_REVEAL_INDICATOR_ELEMENT_TYPES.includes(data.type)
|
|
11751
|
+
) {
|
|
11752
|
+
return invalidFromErrorFactory(
|
|
11753
|
+
errorFactory,
|
|
11754
|
+
`${ownerLabel} element indicator can only be provided for text revealing elements`,
|
|
11755
|
+
{
|
|
11756
|
+
[ownerIdField]: ownerId,
|
|
11757
|
+
elementId,
|
|
11758
|
+
field: "indicator",
|
|
11759
|
+
},
|
|
11760
|
+
);
|
|
11761
|
+
}
|
|
11762
|
+
|
|
11763
|
+
if (
|
|
11764
|
+
data.content !== undefined &&
|
|
11765
|
+
!LAYOUT_TEXT_CONTENT_ELEMENT_TYPES.includes(data.type)
|
|
11766
|
+
) {
|
|
11767
|
+
return invalidFromErrorFactory(
|
|
11768
|
+
errorFactory,
|
|
11769
|
+
`${ownerLabel} element content can only be provided for text elements`,
|
|
11770
|
+
{
|
|
11771
|
+
[ownerIdField]: ownerId,
|
|
11772
|
+
elementId,
|
|
11773
|
+
field: "content",
|
|
11774
|
+
},
|
|
11775
|
+
);
|
|
11776
|
+
}
|
|
11777
|
+
|
|
11386
11778
|
if (
|
|
11387
11779
|
data.type === "spritesheet-animation" ||
|
|
11388
11780
|
data.resourceId !== undefined ||
|
|
@@ -11483,6 +11875,66 @@ const validateVisualElementReferenceTargets = ({
|
|
|
11483
11875
|
}
|
|
11484
11876
|
}
|
|
11485
11877
|
|
|
11878
|
+
for (const stateName of ["revealing", "complete"]) {
|
|
11879
|
+
const visual = data.indicator?.[stateName];
|
|
11880
|
+
if (
|
|
11881
|
+
visual?.kind === "spritesheet" ||
|
|
11882
|
+
visual?.resourceId !== undefined ||
|
|
11883
|
+
visual?.animationName !== undefined
|
|
11884
|
+
) {
|
|
11885
|
+
const spritesheet = state.spritesheets?.items?.[visual.resourceId];
|
|
11886
|
+
if (!isPlainObject(spritesheet) || spritesheet.type === "folder") {
|
|
11887
|
+
return invalidFromErrorFactory(
|
|
11888
|
+
errorFactory,
|
|
11889
|
+
`${ownerLabel} element indicator.${stateName}.resourceId must reference an existing non-folder spritesheet`,
|
|
11890
|
+
{
|
|
11891
|
+
[ownerIdField]: ownerId,
|
|
11892
|
+
elementId,
|
|
11893
|
+
field: `indicator.${stateName}.resourceId`,
|
|
11894
|
+
targetId: visual.resourceId,
|
|
11895
|
+
},
|
|
11896
|
+
);
|
|
11897
|
+
}
|
|
11898
|
+
|
|
11899
|
+
if (
|
|
11900
|
+
!isNonEmptyString(visual.animationName) ||
|
|
11901
|
+
!isPlainObject(spritesheet.animations?.[visual.animationName])
|
|
11902
|
+
) {
|
|
11903
|
+
return invalidFromErrorFactory(
|
|
11904
|
+
errorFactory,
|
|
11905
|
+
`${ownerLabel} element indicator.${stateName}.animationName must reference an existing spritesheet animation`,
|
|
11906
|
+
{
|
|
11907
|
+
[ownerIdField]: ownerId,
|
|
11908
|
+
elementId,
|
|
11909
|
+
field: `indicator.${stateName}.animationName`,
|
|
11910
|
+
targetId: visual.animationName,
|
|
11911
|
+
},
|
|
11912
|
+
);
|
|
11913
|
+
}
|
|
11914
|
+
|
|
11915
|
+
continue;
|
|
11916
|
+
}
|
|
11917
|
+
|
|
11918
|
+
const imageId = visual?.imageId;
|
|
11919
|
+
if (imageId === undefined) {
|
|
11920
|
+
continue;
|
|
11921
|
+
}
|
|
11922
|
+
|
|
11923
|
+
const image = state.images.items[imageId];
|
|
11924
|
+
if (!isPlainObject(image) || image.type === "folder") {
|
|
11925
|
+
return invalidFromErrorFactory(
|
|
11926
|
+
errorFactory,
|
|
11927
|
+
`${ownerLabel} element indicator.${stateName}.imageId must reference an existing non-folder image`,
|
|
11928
|
+
{
|
|
11929
|
+
[ownerIdField]: ownerId,
|
|
11930
|
+
elementId,
|
|
11931
|
+
field: `indicator.${stateName}.imageId`,
|
|
11932
|
+
targetId: imageId,
|
|
11933
|
+
},
|
|
11934
|
+
);
|
|
11935
|
+
}
|
|
11936
|
+
}
|
|
11937
|
+
|
|
11486
11938
|
if (data.hoverSoundId !== undefined) {
|
|
11487
11939
|
const sound = state.sounds.items[data.hoverSoundId];
|
|
11488
11940
|
if (!isPlainObject(sound) || sound.type === "folder") {
|
|
@@ -11710,6 +12162,23 @@ const validateVisualElementReferenceTargets = ({
|
|
|
11710
12162
|
}
|
|
11711
12163
|
}
|
|
11712
12164
|
|
|
12165
|
+
for (const { index, resourceId } of getLayoutTextContentReferenceEntries(
|
|
12166
|
+
data.content,
|
|
12167
|
+
)) {
|
|
12168
|
+
if (!isVariableReferenceTarget(state, resourceId)) {
|
|
12169
|
+
return invalidFromErrorFactory(
|
|
12170
|
+
errorFactory,
|
|
12171
|
+
`${ownerLabel} element content.${index}.reference.resourceId must reference an existing non-folder variable`,
|
|
12172
|
+
{
|
|
12173
|
+
[ownerIdField]: ownerId,
|
|
12174
|
+
elementId,
|
|
12175
|
+
field: `content.${index}.reference.resourceId`,
|
|
12176
|
+
targetId: resourceId,
|
|
12177
|
+
},
|
|
12178
|
+
);
|
|
12179
|
+
}
|
|
12180
|
+
}
|
|
12181
|
+
|
|
11713
12182
|
if (data.variableId !== undefined) {
|
|
11714
12183
|
if (!isVariableReferenceTarget(state, data.variableId)) {
|
|
11715
12184
|
return invalidFromErrorFactory(
|
|
@@ -17736,6 +18205,16 @@ const COMMAND_DEFINITIONS = [
|
|
|
17736
18205
|
"payload.parentId must reference a folder sprite item",
|
|
17737
18206
|
);
|
|
17738
18207
|
}
|
|
18208
|
+
|
|
18209
|
+
const parentNode = findTreeNode({
|
|
18210
|
+
nodes: collection.tree,
|
|
18211
|
+
nodeId: parentId,
|
|
18212
|
+
});
|
|
18213
|
+
if (!parentNode) {
|
|
18214
|
+
return invalidPrecondition(
|
|
18215
|
+
"payload.parentId must reference a folder sprite item in the tree",
|
|
18216
|
+
);
|
|
18217
|
+
}
|
|
17739
18218
|
}
|
|
17740
18219
|
|
|
17741
18220
|
if (payload.positionTargetId !== undefined) {
|
|
@@ -17745,6 +18224,16 @@ const COMMAND_DEFINITIONS = [
|
|
|
17745
18224
|
);
|
|
17746
18225
|
}
|
|
17747
18226
|
|
|
18227
|
+
const targetNode = findTreeNode({
|
|
18228
|
+
nodes: collection.tree,
|
|
18229
|
+
nodeId: payload.positionTargetId,
|
|
18230
|
+
});
|
|
18231
|
+
if (!targetNode) {
|
|
18232
|
+
return invalidPrecondition(
|
|
18233
|
+
"payload.positionTargetId must reference an existing sprite item in the tree",
|
|
18234
|
+
);
|
|
18235
|
+
}
|
|
18236
|
+
|
|
17748
18237
|
const targetParentId = getNodeParentId({
|
|
17749
18238
|
tree: collection.tree,
|
|
17750
18239
|
nodeId: payload.positionTargetId,
|
|
@@ -18076,6 +18565,11 @@ const COMMAND_DEFINITIONS = [
|
|
|
18076
18565
|
nodes: collection.tree,
|
|
18077
18566
|
nodeId: payload.spriteId,
|
|
18078
18567
|
});
|
|
18568
|
+
if (!currentNode) {
|
|
18569
|
+
return invalidPrecondition(
|
|
18570
|
+
"payload.spriteId must reference an existing sprite item in the tree",
|
|
18571
|
+
);
|
|
18572
|
+
}
|
|
18079
18573
|
|
|
18080
18574
|
if (payload.parentId !== undefined && payload.parentId !== null) {
|
|
18081
18575
|
const parentItem = collection.items[payload.parentId];
|
|
@@ -18085,6 +18579,16 @@ const COMMAND_DEFINITIONS = [
|
|
|
18085
18579
|
);
|
|
18086
18580
|
}
|
|
18087
18581
|
|
|
18582
|
+
const parentNode = findTreeNode({
|
|
18583
|
+
nodes: collection.tree,
|
|
18584
|
+
nodeId: payload.parentId,
|
|
18585
|
+
});
|
|
18586
|
+
if (!parentNode) {
|
|
18587
|
+
return invalidPrecondition(
|
|
18588
|
+
"payload.parentId must reference a folder sprite item in the tree",
|
|
18589
|
+
);
|
|
18590
|
+
}
|
|
18591
|
+
|
|
18088
18592
|
const descendantIds = new Set(
|
|
18089
18593
|
collectTreeDescendantIds({
|
|
18090
18594
|
node: currentNode,
|
|
@@ -18111,6 +18615,16 @@ const COMMAND_DEFINITIONS = [
|
|
|
18111
18615
|
);
|
|
18112
18616
|
}
|
|
18113
18617
|
|
|
18618
|
+
const targetNode = findTreeNode({
|
|
18619
|
+
nodes: collection.tree,
|
|
18620
|
+
nodeId: payload.positionTargetId,
|
|
18621
|
+
});
|
|
18622
|
+
if (!targetNode) {
|
|
18623
|
+
return invalidPrecondition(
|
|
18624
|
+
"payload.positionTargetId must reference an existing sprite item in the tree",
|
|
18625
|
+
);
|
|
18626
|
+
}
|
|
18627
|
+
|
|
18114
18628
|
const targetParentId = getNodeParentId({
|
|
18115
18629
|
tree: collection.tree,
|
|
18116
18630
|
nodeId: payload.positionTargetId,
|