narrat 1.2.1 → 1.3.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/lib/index.esm.js +275 -245
- package/lib/index.js +275 -245
- package/lib/stores/main-store.d.ts +1 -0
- package/lib/stores/vm-store.d.ts +1 -0
- package/lib/vm/commands/run.d.ts +2 -0
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version: 1.
|
|
1
|
+
// Version: 1.3.0 - June 25, 2022 18:05:43
|
|
2
2
|
import 'es6-promise/auto';
|
|
3
3
|
import { ref, reactive, readonly, defineComponent, openBlock, createElementBlock, normalizeStyle, createElementVNode, createCommentVNode, Fragment, renderList, normalizeClass, createBlock, Transition, withCtx, renderSlot, createTextVNode, computed, resolveComponent, withDirectives, vModelText, toDisplayString, TransitionGroup, createVNode, createApp } from 'vue';
|
|
4
4
|
import { defineStore, mapState, createPinia } from 'pinia';
|
|
@@ -3560,32 +3560,178 @@ function randomId() {
|
|
|
3560
3560
|
return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
|
|
3561
3561
|
}
|
|
3562
3562
|
|
|
3563
|
-
//
|
|
3564
|
-
|
|
3563
|
+
// Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
|
|
3564
|
+
// addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
|
|
3565
|
+
// deleteNotification(id: string): Deletes a notification from the state
|
|
3566
|
+
const useNotifications = defineStore('notifications', {
|
|
3567
|
+
state: () => ({ notifications: {} }),
|
|
3568
|
+
actions: {
|
|
3569
|
+
async addNotification(text) {
|
|
3570
|
+
const id = `${Date.now()}-${Math.random() * 10000}`;
|
|
3571
|
+
this.notifications[id] = {
|
|
3572
|
+
text,
|
|
3573
|
+
};
|
|
3574
|
+
if (getConfig().notifications.alsoPrintInDialogue) {
|
|
3575
|
+
writeText(`[NOTIFICATION] ${text}`);
|
|
3576
|
+
}
|
|
3577
|
+
await timeout(getConfig().notifications.timeOnScreen * 1000);
|
|
3578
|
+
this.deleteNotification(id);
|
|
3579
|
+
},
|
|
3580
|
+
deleteNotification(id) {
|
|
3581
|
+
delete this.notifications[id];
|
|
3582
|
+
},
|
|
3583
|
+
},
|
|
3584
|
+
});
|
|
3585
|
+
|
|
3586
|
+
// create a pinia store named inventory with a state containing items and actions to add and delete items
|
|
3587
|
+
// create a pinia store named inventory with a state of type ItemState and actions to add and delete items. Adding items should increase the amount of any existing item that matches the id.
|
|
3588
|
+
const useInventory = defineStore('inventory', {
|
|
3565
3589
|
state: () => ({
|
|
3566
|
-
|
|
3590
|
+
items: {},
|
|
3567
3591
|
}),
|
|
3568
3592
|
actions: {
|
|
3569
3593
|
generateSaveData() {
|
|
3570
3594
|
return {
|
|
3571
|
-
|
|
3595
|
+
items: this.items,
|
|
3572
3596
|
};
|
|
3573
3597
|
},
|
|
3574
|
-
loadSaveData(
|
|
3575
|
-
this.
|
|
3598
|
+
loadSaveData(save) {
|
|
3599
|
+
this.items = { ...this.items, ...save.items };
|
|
3576
3600
|
},
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3601
|
+
setupItems(items) {
|
|
3602
|
+
Object.keys(items).forEach((key) => {
|
|
3603
|
+
this.items[key] = {
|
|
3604
|
+
amount: 0,
|
|
3605
|
+
id: key,
|
|
3606
|
+
};
|
|
3582
3607
|
});
|
|
3583
3608
|
},
|
|
3584
|
-
|
|
3585
|
-
|
|
3609
|
+
getExistingItem(id) {
|
|
3610
|
+
return this.items[id];
|
|
3586
3611
|
},
|
|
3587
|
-
|
|
3588
|
-
this.
|
|
3612
|
+
getItemAmount(id) {
|
|
3613
|
+
return this.getExistingItem(id)?.amount || 0;
|
|
3614
|
+
},
|
|
3615
|
+
add(item) {
|
|
3616
|
+
const existingItem = this.getExistingItem(item.id);
|
|
3617
|
+
if (existingItem) {
|
|
3618
|
+
existingItem.amount += item.amount;
|
|
3619
|
+
}
|
|
3620
|
+
else {
|
|
3621
|
+
this.items[item.id] = { ...item };
|
|
3622
|
+
}
|
|
3623
|
+
useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3624
|
+
},
|
|
3625
|
+
remove(item) {
|
|
3626
|
+
const existingItem = this.getExistingItem(item.id);
|
|
3627
|
+
if (existingItem) {
|
|
3628
|
+
existingItem.amount -= item.amount;
|
|
3629
|
+
useNotifications().addNotification(`Lost item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3630
|
+
if (existingItem.amount <= 0) {
|
|
3631
|
+
this.deleteItem(item.id);
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
},
|
|
3635
|
+
deleteItem(id) {
|
|
3636
|
+
const existingItem = this.getExistingItem(id);
|
|
3637
|
+
if (existingItem) {
|
|
3638
|
+
this.items[id].amount = 0;
|
|
3639
|
+
}
|
|
3640
|
+
},
|
|
3641
|
+
},
|
|
3642
|
+
});
|
|
3643
|
+
|
|
3644
|
+
const everyObject = (object, predicate) => {
|
|
3645
|
+
for (const key in object) {
|
|
3646
|
+
if (!predicate(object[key])) {
|
|
3647
|
+
return false;
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
return true;
|
|
3651
|
+
};
|
|
3652
|
+
const filterObject = (object, predicate) => {
|
|
3653
|
+
const result = {};
|
|
3654
|
+
for (const key in object) {
|
|
3655
|
+
if (predicate(object[key])) {
|
|
3656
|
+
result[key] = object[key];
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
return result;
|
|
3660
|
+
};
|
|
3661
|
+
|
|
3662
|
+
const useQuests = defineStore('quests', {
|
|
3663
|
+
state: () => ({
|
|
3664
|
+
quests: {},
|
|
3665
|
+
}),
|
|
3666
|
+
actions: {
|
|
3667
|
+
getQuest(questId) {
|
|
3668
|
+
const quest = this.quests[questId];
|
|
3669
|
+
if (quest) {
|
|
3670
|
+
return quest;
|
|
3671
|
+
}
|
|
3672
|
+
error(`Quest ${questId} doesn't exist!`);
|
|
3673
|
+
},
|
|
3674
|
+
getObjective(quest, objectiveId) {
|
|
3675
|
+
const questObjective = this.getQuest(quest).objectives[objectiveId];
|
|
3676
|
+
if (questObjective) {
|
|
3677
|
+
return questObjective;
|
|
3678
|
+
}
|
|
3679
|
+
error(`Objective ${objectiveId} doesn't exist in quest ${quest}!`);
|
|
3680
|
+
},
|
|
3681
|
+
setupQuests(quests) {
|
|
3682
|
+
// iterate through quests to generate quest states to add to this.quests object
|
|
3683
|
+
for (const key of Object.keys(quests)) {
|
|
3684
|
+
const data = quests[key];
|
|
3685
|
+
this.quests[key] = {
|
|
3686
|
+
id: key,
|
|
3687
|
+
state: 'hidden',
|
|
3688
|
+
objectives: {},
|
|
3689
|
+
};
|
|
3690
|
+
// iterate through data.objectives to populate the objectives array of this.quests[key]
|
|
3691
|
+
for (const objectiveKey of Object.keys(data.objectives)) {
|
|
3692
|
+
const objective = data.objectives[objectiveKey];
|
|
3693
|
+
this.quests[key].objectives[objectiveKey] = {
|
|
3694
|
+
id: objectiveKey,
|
|
3695
|
+
state: objective.hidden ? 'hidden' : 'unlocked',
|
|
3696
|
+
};
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
},
|
|
3700
|
+
startQuest(questId) {
|
|
3701
|
+
this.getQuest(questId).state = 'unlocked';
|
|
3702
|
+
useNotifications().addNotification(`Started quest: ${getQuestConfig(questId).title}`);
|
|
3703
|
+
},
|
|
3704
|
+
startObjective(questId, objectiveId) {
|
|
3705
|
+
this.getObjective(questId, objectiveId).state = 'unlocked';
|
|
3706
|
+
useNotifications().addNotification(`New quest objective: ${getObjectiveConfig(questId, objectiveId).description}`);
|
|
3707
|
+
},
|
|
3708
|
+
completeObjective(questId, objectiveId) {
|
|
3709
|
+
this.getObjective(questId, objectiveId).state = 'completed';
|
|
3710
|
+
useNotifications().addNotification(`Objective completed!`);
|
|
3711
|
+
},
|
|
3712
|
+
completeQuest(questId, ending) {
|
|
3713
|
+
this.getQuest(questId).state = 'completed';
|
|
3714
|
+
if (ending) {
|
|
3715
|
+
this.getQuest(questId).ending = ending;
|
|
3716
|
+
}
|
|
3717
|
+
useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
|
|
3718
|
+
},
|
|
3719
|
+
isQuestCompleted(questId) {
|
|
3720
|
+
const quest = this.getQuest(questId);
|
|
3721
|
+
return everyObject(quest.objectives, (objective) => objective.state === 'completed');
|
|
3722
|
+
},
|
|
3723
|
+
removeQuest(id) {
|
|
3724
|
+
delete this.quests[id];
|
|
3725
|
+
},
|
|
3726
|
+
generateSaveData() {
|
|
3727
|
+
return {
|
|
3728
|
+
quests: {
|
|
3729
|
+
...this.quests,
|
|
3730
|
+
},
|
|
3731
|
+
};
|
|
3732
|
+
},
|
|
3733
|
+
loadSaveData(data) {
|
|
3734
|
+
this.quests = data.quests;
|
|
3589
3735
|
},
|
|
3590
3736
|
},
|
|
3591
3737
|
});
|
|
@@ -3722,122 +3868,6 @@ var deepmerge_1 = deepmerge;
|
|
|
3722
3868
|
|
|
3723
3869
|
var cjs = deepmerge_1;
|
|
3724
3870
|
|
|
3725
|
-
// Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
|
|
3726
|
-
// setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
|
|
3727
|
-
// setStat(stat: string, value: number): Sets the value of a stat
|
|
3728
|
-
// addStat(stat: string, value: number): Adds a value to a stat
|
|
3729
|
-
// generateSaveData(): Function that generates a HudSave object from the data in the state
|
|
3730
|
-
// loadSaveData(data: HudSave): Function that loads the data into the state
|
|
3731
|
-
const useHud = defineStore('hud', {
|
|
3732
|
-
state: () => ({
|
|
3733
|
-
hudStats: {},
|
|
3734
|
-
}),
|
|
3735
|
-
actions: {
|
|
3736
|
-
setupHudStats(stats) {
|
|
3737
|
-
for (const stat in stats) {
|
|
3738
|
-
this.hudStats[stat] = {
|
|
3739
|
-
value: stats[stat].startingValue,
|
|
3740
|
-
};
|
|
3741
|
-
}
|
|
3742
|
-
},
|
|
3743
|
-
setStat(stat, value) {
|
|
3744
|
-
this.hudStats[stat].value = value;
|
|
3745
|
-
},
|
|
3746
|
-
addStat(stat, value) {
|
|
3747
|
-
this.hudStats[stat].value += value;
|
|
3748
|
-
},
|
|
3749
|
-
generateSaveData() {
|
|
3750
|
-
return {
|
|
3751
|
-
hudStats: this.hudStats,
|
|
3752
|
-
};
|
|
3753
|
-
},
|
|
3754
|
-
loadSaveData(data) {
|
|
3755
|
-
this.hudStats = cjs(this.hudStats, data.hudStats);
|
|
3756
|
-
},
|
|
3757
|
-
},
|
|
3758
|
-
});
|
|
3759
|
-
|
|
3760
|
-
// Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
|
|
3761
|
-
// addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
|
|
3762
|
-
// deleteNotification(id: string): Deletes a notification from the state
|
|
3763
|
-
const useNotifications = defineStore('notifications', {
|
|
3764
|
-
state: () => ({ notifications: {} }),
|
|
3765
|
-
actions: {
|
|
3766
|
-
async addNotification(text) {
|
|
3767
|
-
const id = `${Date.now()}-${Math.random() * 10000}`;
|
|
3768
|
-
this.notifications[id] = {
|
|
3769
|
-
text,
|
|
3770
|
-
};
|
|
3771
|
-
if (getConfig().notifications.alsoPrintInDialogue) {
|
|
3772
|
-
writeText(`[NOTIFICATION] ${text}`);
|
|
3773
|
-
}
|
|
3774
|
-
await timeout(getConfig().notifications.timeOnScreen * 1000);
|
|
3775
|
-
this.deleteNotification(id);
|
|
3776
|
-
},
|
|
3777
|
-
deleteNotification(id) {
|
|
3778
|
-
delete this.notifications[id];
|
|
3779
|
-
},
|
|
3780
|
-
},
|
|
3781
|
-
});
|
|
3782
|
-
|
|
3783
|
-
// create a pinia store named inventory with a state containing items and actions to add and delete items
|
|
3784
|
-
// create a pinia store named inventory with a state of type ItemState and actions to add and delete items. Adding items should increase the amount of any existing item that matches the id.
|
|
3785
|
-
const useInventory = defineStore('inventory', {
|
|
3786
|
-
state: () => ({
|
|
3787
|
-
items: {},
|
|
3788
|
-
}),
|
|
3789
|
-
actions: {
|
|
3790
|
-
generateSaveData() {
|
|
3791
|
-
return {
|
|
3792
|
-
items: this.items,
|
|
3793
|
-
};
|
|
3794
|
-
},
|
|
3795
|
-
loadSaveData(save) {
|
|
3796
|
-
this.items = { ...this.items, ...save.items };
|
|
3797
|
-
},
|
|
3798
|
-
setupItems(items) {
|
|
3799
|
-
Object.keys(items).forEach((key) => {
|
|
3800
|
-
this.items[key] = {
|
|
3801
|
-
amount: 0,
|
|
3802
|
-
id: key,
|
|
3803
|
-
};
|
|
3804
|
-
});
|
|
3805
|
-
},
|
|
3806
|
-
getExistingItem(id) {
|
|
3807
|
-
return this.items[id];
|
|
3808
|
-
},
|
|
3809
|
-
getItemAmount(id) {
|
|
3810
|
-
return this.getExistingItem(id)?.amount || 0;
|
|
3811
|
-
},
|
|
3812
|
-
add(item) {
|
|
3813
|
-
const existingItem = this.getExistingItem(item.id);
|
|
3814
|
-
if (existingItem) {
|
|
3815
|
-
existingItem.amount += item.amount;
|
|
3816
|
-
}
|
|
3817
|
-
else {
|
|
3818
|
-
this.items[item.id] = { ...item };
|
|
3819
|
-
}
|
|
3820
|
-
useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3821
|
-
},
|
|
3822
|
-
remove(item) {
|
|
3823
|
-
const existingItem = this.getExistingItem(item.id);
|
|
3824
|
-
if (existingItem) {
|
|
3825
|
-
existingItem.amount -= item.amount;
|
|
3826
|
-
useNotifications().addNotification(`Lost item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3827
|
-
if (existingItem.amount <= 0) {
|
|
3828
|
-
this.deleteItem(item.id);
|
|
3829
|
-
}
|
|
3830
|
-
}
|
|
3831
|
-
},
|
|
3832
|
-
deleteItem(id) {
|
|
3833
|
-
const existingItem = this.getExistingItem(id);
|
|
3834
|
-
if (existingItem) {
|
|
3835
|
-
this.items[id].amount = 0;
|
|
3836
|
-
}
|
|
3837
|
-
},
|
|
3838
|
-
},
|
|
3839
|
-
});
|
|
3840
|
-
|
|
3841
3871
|
// Create a pinia store named skills with a state using the type Skills, with actions:
|
|
3842
3872
|
// setupSkillCheck(skillCheck: SkillCheckState, id: string)
|
|
3843
3873
|
// passSkillCheck(skillCheckId: string)
|
|
@@ -3885,6 +3915,9 @@ const useSkills = defineStore('skills', {
|
|
|
3885
3915
|
},
|
|
3886
3916
|
addXp(skill, xp) {
|
|
3887
3917
|
const skillData = this.skills[skill];
|
|
3918
|
+
if (!skillData) {
|
|
3919
|
+
error(`Skill ${skill} doesn't exist`);
|
|
3920
|
+
}
|
|
3888
3921
|
skillData.xp += xp;
|
|
3889
3922
|
if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
|
|
3890
3923
|
skillData.xp = 0;
|
|
@@ -3925,101 +3958,6 @@ function getFile(url) {
|
|
|
3925
3958
|
});
|
|
3926
3959
|
}
|
|
3927
3960
|
|
|
3928
|
-
const everyObject = (object, predicate) => {
|
|
3929
|
-
for (const key in object) {
|
|
3930
|
-
if (!predicate(object[key])) {
|
|
3931
|
-
return false;
|
|
3932
|
-
}
|
|
3933
|
-
}
|
|
3934
|
-
return true;
|
|
3935
|
-
};
|
|
3936
|
-
const filterObject = (object, predicate) => {
|
|
3937
|
-
const result = {};
|
|
3938
|
-
for (const key in object) {
|
|
3939
|
-
if (predicate(object[key])) {
|
|
3940
|
-
result[key] = object[key];
|
|
3941
|
-
}
|
|
3942
|
-
}
|
|
3943
|
-
return result;
|
|
3944
|
-
};
|
|
3945
|
-
|
|
3946
|
-
const useQuests = defineStore('quests', {
|
|
3947
|
-
state: () => ({
|
|
3948
|
-
quests: {},
|
|
3949
|
-
}),
|
|
3950
|
-
actions: {
|
|
3951
|
-
getQuest(questId) {
|
|
3952
|
-
const quest = this.quests[questId];
|
|
3953
|
-
if (quest) {
|
|
3954
|
-
return quest;
|
|
3955
|
-
}
|
|
3956
|
-
error(`Quest ${questId} doesn't exist!`);
|
|
3957
|
-
},
|
|
3958
|
-
getObjective(quest, objectiveId) {
|
|
3959
|
-
const questObjective = this.getQuest(quest).objectives[objectiveId];
|
|
3960
|
-
if (questObjective) {
|
|
3961
|
-
return questObjective;
|
|
3962
|
-
}
|
|
3963
|
-
error(`Objective ${objectiveId} doesn't exist in quest ${quest}!`);
|
|
3964
|
-
},
|
|
3965
|
-
setupQuests(quests) {
|
|
3966
|
-
// iterate through quests to generate quest states to add to this.quests object
|
|
3967
|
-
for (const key of Object.keys(quests)) {
|
|
3968
|
-
const data = quests[key];
|
|
3969
|
-
this.quests[key] = {
|
|
3970
|
-
id: key,
|
|
3971
|
-
state: 'hidden',
|
|
3972
|
-
objectives: {},
|
|
3973
|
-
};
|
|
3974
|
-
// iterate through data.objectives to populate the objectives array of this.quests[key]
|
|
3975
|
-
for (const objectiveKey of Object.keys(data.objectives)) {
|
|
3976
|
-
const objective = data.objectives[objectiveKey];
|
|
3977
|
-
this.quests[key].objectives[objectiveKey] = {
|
|
3978
|
-
id: objectiveKey,
|
|
3979
|
-
state: objective.hidden ? 'hidden' : 'unlocked',
|
|
3980
|
-
};
|
|
3981
|
-
}
|
|
3982
|
-
}
|
|
3983
|
-
},
|
|
3984
|
-
startQuest(questId) {
|
|
3985
|
-
this.getQuest(questId).state = 'unlocked';
|
|
3986
|
-
useNotifications().addNotification(`Started quest: ${getQuestConfig(questId).title}`);
|
|
3987
|
-
},
|
|
3988
|
-
startObjective(questId, objectiveId) {
|
|
3989
|
-
this.getObjective(questId, objectiveId).state = 'unlocked';
|
|
3990
|
-
useNotifications().addNotification(`New quest objective: ${getObjectiveConfig(questId, objectiveId).description}`);
|
|
3991
|
-
},
|
|
3992
|
-
completeObjective(questId, objectiveId) {
|
|
3993
|
-
this.getObjective(questId, objectiveId).state = 'completed';
|
|
3994
|
-
useNotifications().addNotification(`Objective completed!`);
|
|
3995
|
-
},
|
|
3996
|
-
completeQuest(questId, ending) {
|
|
3997
|
-
this.getQuest(questId).state = 'completed';
|
|
3998
|
-
if (ending) {
|
|
3999
|
-
this.getQuest(questId).ending = ending;
|
|
4000
|
-
}
|
|
4001
|
-
useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
|
|
4002
|
-
},
|
|
4003
|
-
isQuestCompleted(questId) {
|
|
4004
|
-
const quest = this.getQuest(questId);
|
|
4005
|
-
return everyObject(quest.objectives, (objective) => objective.state === 'completed');
|
|
4006
|
-
},
|
|
4007
|
-
removeQuest(id) {
|
|
4008
|
-
delete this.quests[id];
|
|
4009
|
-
},
|
|
4010
|
-
generateSaveData() {
|
|
4011
|
-
return {
|
|
4012
|
-
quests: {
|
|
4013
|
-
...this.quests,
|
|
4014
|
-
},
|
|
4015
|
-
};
|
|
4016
|
-
},
|
|
4017
|
-
loadSaveData(data) {
|
|
4018
|
-
this.quests = data.quests;
|
|
4019
|
-
},
|
|
4020
|
-
},
|
|
4021
|
-
});
|
|
4022
|
-
|
|
4023
3961
|
// Create a pinia store named screens with a state using the type ScreenState, with actions:
|
|
4024
3962
|
// setScreen(screen: string): Sets the current screen to the given screen
|
|
4025
3963
|
// setButtons(buttons: { [key: string]: ButtonConfig }): Adds buttons to the buttons state by using the values in the buttons config object
|
|
@@ -4311,6 +4249,7 @@ const useVM = defineStore('vm', {
|
|
|
4311
4249
|
data: {},
|
|
4312
4250
|
lastLabel: 'main',
|
|
4313
4251
|
script: {},
|
|
4252
|
+
labelStack: ['main'],
|
|
4314
4253
|
}),
|
|
4315
4254
|
actions: {
|
|
4316
4255
|
generateSaveData() {
|
|
@@ -4427,6 +4366,19 @@ const useVM = defineStore('vm', {
|
|
|
4427
4366
|
const cmd = this.currentLine;
|
|
4428
4367
|
await runCommand(cmd);
|
|
4429
4368
|
},
|
|
4369
|
+
async runLabelFunction(label) {
|
|
4370
|
+
const branch = this.script[label];
|
|
4371
|
+
if (!branch) {
|
|
4372
|
+
console.error(`Label ${branch} doesn't exist`);
|
|
4373
|
+
}
|
|
4374
|
+
const stack = {
|
|
4375
|
+
currentIndex: 0,
|
|
4376
|
+
branch: branch,
|
|
4377
|
+
label,
|
|
4378
|
+
};
|
|
4379
|
+
this.addStack(stack);
|
|
4380
|
+
await this.runLine();
|
|
4381
|
+
},
|
|
4430
4382
|
runLabel(label) {
|
|
4431
4383
|
const branch = this.script[label];
|
|
4432
4384
|
if (!branch) {
|
|
@@ -4455,6 +4407,88 @@ const useVM = defineStore('vm', {
|
|
|
4455
4407
|
},
|
|
4456
4408
|
});
|
|
4457
4409
|
|
|
4410
|
+
function processText(text) {
|
|
4411
|
+
const vmStore = useVM();
|
|
4412
|
+
const skillStore = useSkills();
|
|
4413
|
+
return text.replace(/%{[^}]*}/g, (match) => {
|
|
4414
|
+
const key = match.substr(2, match.length - 3);
|
|
4415
|
+
const searchableState = {
|
|
4416
|
+
data: vmStore.data,
|
|
4417
|
+
skills: skillStore.skills,
|
|
4418
|
+
items: useInventory().items,
|
|
4419
|
+
quests: useQuests().quests,
|
|
4420
|
+
};
|
|
4421
|
+
const [obj, newKey] = findDataHelper(searchableState, key);
|
|
4422
|
+
return obj[newKey];
|
|
4423
|
+
});
|
|
4424
|
+
}
|
|
4425
|
+
|
|
4426
|
+
// Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
|
|
4427
|
+
const useDialogStore = defineStore('dialog', {
|
|
4428
|
+
state: () => ({
|
|
4429
|
+
dialog: [],
|
|
4430
|
+
}),
|
|
4431
|
+
actions: {
|
|
4432
|
+
generateSaveData() {
|
|
4433
|
+
return {
|
|
4434
|
+
dialog: this.dialog,
|
|
4435
|
+
};
|
|
4436
|
+
},
|
|
4437
|
+
loadSaveData(data) {
|
|
4438
|
+
this.dialog = data.dialog;
|
|
4439
|
+
},
|
|
4440
|
+
addDialog(dialog) {
|
|
4441
|
+
this.dialog.push({
|
|
4442
|
+
...dialog,
|
|
4443
|
+
interactive: dialog.interactive ?? false,
|
|
4444
|
+
id: randomId(),
|
|
4445
|
+
text: processText(dialog.text),
|
|
4446
|
+
});
|
|
4447
|
+
},
|
|
4448
|
+
clearDialog() {
|
|
4449
|
+
this.dialog.splice(0, this.dialog.length);
|
|
4450
|
+
},
|
|
4451
|
+
reset() {
|
|
4452
|
+
this.dialog = [];
|
|
4453
|
+
},
|
|
4454
|
+
},
|
|
4455
|
+
});
|
|
4456
|
+
|
|
4457
|
+
// Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
|
|
4458
|
+
// setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
|
|
4459
|
+
// setStat(stat: string, value: number): Sets the value of a stat
|
|
4460
|
+
// addStat(stat: string, value: number): Adds a value to a stat
|
|
4461
|
+
// generateSaveData(): Function that generates a HudSave object from the data in the state
|
|
4462
|
+
// loadSaveData(data: HudSave): Function that loads the data into the state
|
|
4463
|
+
const useHud = defineStore('hud', {
|
|
4464
|
+
state: () => ({
|
|
4465
|
+
hudStats: {},
|
|
4466
|
+
}),
|
|
4467
|
+
actions: {
|
|
4468
|
+
setupHudStats(stats) {
|
|
4469
|
+
for (const stat in stats) {
|
|
4470
|
+
this.hudStats[stat] = {
|
|
4471
|
+
value: stats[stat].startingValue,
|
|
4472
|
+
};
|
|
4473
|
+
}
|
|
4474
|
+
},
|
|
4475
|
+
setStat(stat, value) {
|
|
4476
|
+
this.hudStats[stat].value = value;
|
|
4477
|
+
},
|
|
4478
|
+
addStat(stat, value) {
|
|
4479
|
+
this.hudStats[stat].value += value;
|
|
4480
|
+
},
|
|
4481
|
+
generateSaveData() {
|
|
4482
|
+
return {
|
|
4483
|
+
hudStats: this.hudStats,
|
|
4484
|
+
};
|
|
4485
|
+
},
|
|
4486
|
+
loadSaveData(data) {
|
|
4487
|
+
this.hudStats = cjs(this.hudStats, data.hudStats);
|
|
4488
|
+
},
|
|
4489
|
+
},
|
|
4490
|
+
});
|
|
4491
|
+
|
|
4458
4492
|
function createSkillCheckState() {
|
|
4459
4493
|
const skillCheck = {
|
|
4460
4494
|
passed: false,
|
|
@@ -7722,22 +7756,6 @@ styleInject(css_248z$8);
|
|
|
7722
7756
|
|
|
7723
7757
|
script$7.render = render$7;
|
|
7724
7758
|
|
|
7725
|
-
function processText(text) {
|
|
7726
|
-
const vmStore = useVM();
|
|
7727
|
-
const skillStore = useSkills();
|
|
7728
|
-
return text.replace(/%{[^}]*}/g, (match) => {
|
|
7729
|
-
const key = match.substr(2, match.length - 3);
|
|
7730
|
-
const searchableState = {
|
|
7731
|
-
data: vmStore.data,
|
|
7732
|
-
skills: skillStore.skills,
|
|
7733
|
-
items: useInventory().items,
|
|
7734
|
-
quests: useQuests().quests,
|
|
7735
|
-
};
|
|
7736
|
-
const [obj, newKey] = findDataHelper(searchableState, key);
|
|
7737
|
-
return obj[newKey];
|
|
7738
|
-
});
|
|
7739
|
-
}
|
|
7740
|
-
|
|
7741
7759
|
function aspectRatioFit(screenWidth, screenHeight, gameWidth, gameHeight) {
|
|
7742
7760
|
const widthRatio = screenWidth / gameWidth;
|
|
7743
7761
|
const heightRatio = screenHeight / gameHeight;
|
|
@@ -8719,7 +8737,7 @@ var script$d = defineComponent({
|
|
|
8719
8737
|
}
|
|
8720
8738
|
return {
|
|
8721
8739
|
title,
|
|
8722
|
-
text:
|
|
8740
|
+
text: dialogKey.text,
|
|
8723
8741
|
styleId: dialogKey.speaker,
|
|
8724
8742
|
choices: dialogKey.choices,
|
|
8725
8743
|
old: index < this.dialog.length - 1,
|
|
@@ -9439,6 +9457,15 @@ const completeQuestPlugin = new CommandPlugin('complete_quest', async (cmd) => {
|
|
|
9439
9457
|
return useVM().nextLine();
|
|
9440
9458
|
}, generateParser('complete_quest'));
|
|
9441
9459
|
|
|
9460
|
+
// Write a CommandPlugin for running a label using the runLabelFunction of the useVM store
|
|
9461
|
+
const runLabelPlugin = new CommandPlugin('run_label', async (cmd) => {
|
|
9462
|
+
const label = cmd.args[0];
|
|
9463
|
+
if (!label) {
|
|
9464
|
+
error(`run_label command needs a label to argument run`);
|
|
9465
|
+
}
|
|
9466
|
+
await useVM().runLabelFunction(label);
|
|
9467
|
+
}, generateParser('run_label'));
|
|
9468
|
+
|
|
9442
9469
|
function registerBaseCommands(vm) {
|
|
9443
9470
|
vm.addCommand(addItemPlugin);
|
|
9444
9471
|
vm.addCommand(addLevelPlugin);
|
|
@@ -9461,6 +9488,9 @@ function registerBaseCommands(vm) {
|
|
|
9461
9488
|
vm.addCommand(talkCommand);
|
|
9462
9489
|
vm.addCommand(textCommandPlugin);
|
|
9463
9490
|
vm.addCommand(waitCommand);
|
|
9491
|
+
// functions and labels
|
|
9492
|
+
vm.addCommand(jumpCommand);
|
|
9493
|
+
vm.addCommand(runLabelPlugin);
|
|
9464
9494
|
// Quests
|
|
9465
9495
|
vm.addCommand(startQuestPlugin);
|
|
9466
9496
|
vm.addCommand(startObjectivePlugin);
|
|
@@ -9508,7 +9538,7 @@ async function startApp(config, options) {
|
|
|
9508
9538
|
});
|
|
9509
9539
|
registerBaseCommands(vm);
|
|
9510
9540
|
logManager.setupDebugger(options.debug);
|
|
9511
|
-
console.log('%c Narrat game engine – 1.
|
|
9541
|
+
console.log('%c Narrat game engine – 1.3.0 - June 25, 2022 18:05:43', 'background: #222; color: #bada55');
|
|
9512
9542
|
vm.callHook('onNarratSetup');
|
|
9513
9543
|
app.mount('#game-holder');
|
|
9514
9544
|
if (options.debug) {
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version: 1.
|
|
1
|
+
// Version: 1.3.0 - June 25, 2022 18:05:43
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
@@ -3564,32 +3564,178 @@ function randomId() {
|
|
|
3564
3564
|
return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
|
|
3565
3565
|
}
|
|
3566
3566
|
|
|
3567
|
-
//
|
|
3568
|
-
|
|
3567
|
+
// Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
|
|
3568
|
+
// addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
|
|
3569
|
+
// deleteNotification(id: string): Deletes a notification from the state
|
|
3570
|
+
const useNotifications = pinia.defineStore('notifications', {
|
|
3571
|
+
state: () => ({ notifications: {} }),
|
|
3572
|
+
actions: {
|
|
3573
|
+
async addNotification(text) {
|
|
3574
|
+
const id = `${Date.now()}-${Math.random() * 10000}`;
|
|
3575
|
+
this.notifications[id] = {
|
|
3576
|
+
text,
|
|
3577
|
+
};
|
|
3578
|
+
if (getConfig().notifications.alsoPrintInDialogue) {
|
|
3579
|
+
writeText(`[NOTIFICATION] ${text}`);
|
|
3580
|
+
}
|
|
3581
|
+
await timeout(getConfig().notifications.timeOnScreen * 1000);
|
|
3582
|
+
this.deleteNotification(id);
|
|
3583
|
+
},
|
|
3584
|
+
deleteNotification(id) {
|
|
3585
|
+
delete this.notifications[id];
|
|
3586
|
+
},
|
|
3587
|
+
},
|
|
3588
|
+
});
|
|
3589
|
+
|
|
3590
|
+
// create a pinia store named inventory with a state containing items and actions to add and delete items
|
|
3591
|
+
// create a pinia store named inventory with a state of type ItemState and actions to add and delete items. Adding items should increase the amount of any existing item that matches the id.
|
|
3592
|
+
const useInventory = pinia.defineStore('inventory', {
|
|
3569
3593
|
state: () => ({
|
|
3570
|
-
|
|
3594
|
+
items: {},
|
|
3571
3595
|
}),
|
|
3572
3596
|
actions: {
|
|
3573
3597
|
generateSaveData() {
|
|
3574
3598
|
return {
|
|
3575
|
-
|
|
3599
|
+
items: this.items,
|
|
3576
3600
|
};
|
|
3577
3601
|
},
|
|
3578
|
-
loadSaveData(
|
|
3579
|
-
this.
|
|
3602
|
+
loadSaveData(save) {
|
|
3603
|
+
this.items = { ...this.items, ...save.items };
|
|
3580
3604
|
},
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3605
|
+
setupItems(items) {
|
|
3606
|
+
Object.keys(items).forEach((key) => {
|
|
3607
|
+
this.items[key] = {
|
|
3608
|
+
amount: 0,
|
|
3609
|
+
id: key,
|
|
3610
|
+
};
|
|
3586
3611
|
});
|
|
3587
3612
|
},
|
|
3588
|
-
|
|
3589
|
-
|
|
3613
|
+
getExistingItem(id) {
|
|
3614
|
+
return this.items[id];
|
|
3590
3615
|
},
|
|
3591
|
-
|
|
3592
|
-
this.
|
|
3616
|
+
getItemAmount(id) {
|
|
3617
|
+
return this.getExistingItem(id)?.amount || 0;
|
|
3618
|
+
},
|
|
3619
|
+
add(item) {
|
|
3620
|
+
const existingItem = this.getExistingItem(item.id);
|
|
3621
|
+
if (existingItem) {
|
|
3622
|
+
existingItem.amount += item.amount;
|
|
3623
|
+
}
|
|
3624
|
+
else {
|
|
3625
|
+
this.items[item.id] = { ...item };
|
|
3626
|
+
}
|
|
3627
|
+
useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3628
|
+
},
|
|
3629
|
+
remove(item) {
|
|
3630
|
+
const existingItem = this.getExistingItem(item.id);
|
|
3631
|
+
if (existingItem) {
|
|
3632
|
+
existingItem.amount -= item.amount;
|
|
3633
|
+
useNotifications().addNotification(`Lost item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3634
|
+
if (existingItem.amount <= 0) {
|
|
3635
|
+
this.deleteItem(item.id);
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
},
|
|
3639
|
+
deleteItem(id) {
|
|
3640
|
+
const existingItem = this.getExistingItem(id);
|
|
3641
|
+
if (existingItem) {
|
|
3642
|
+
this.items[id].amount = 0;
|
|
3643
|
+
}
|
|
3644
|
+
},
|
|
3645
|
+
},
|
|
3646
|
+
});
|
|
3647
|
+
|
|
3648
|
+
const everyObject = (object, predicate) => {
|
|
3649
|
+
for (const key in object) {
|
|
3650
|
+
if (!predicate(object[key])) {
|
|
3651
|
+
return false;
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
return true;
|
|
3655
|
+
};
|
|
3656
|
+
const filterObject = (object, predicate) => {
|
|
3657
|
+
const result = {};
|
|
3658
|
+
for (const key in object) {
|
|
3659
|
+
if (predicate(object[key])) {
|
|
3660
|
+
result[key] = object[key];
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
return result;
|
|
3664
|
+
};
|
|
3665
|
+
|
|
3666
|
+
const useQuests = pinia.defineStore('quests', {
|
|
3667
|
+
state: () => ({
|
|
3668
|
+
quests: {},
|
|
3669
|
+
}),
|
|
3670
|
+
actions: {
|
|
3671
|
+
getQuest(questId) {
|
|
3672
|
+
const quest = this.quests[questId];
|
|
3673
|
+
if (quest) {
|
|
3674
|
+
return quest;
|
|
3675
|
+
}
|
|
3676
|
+
error(`Quest ${questId} doesn't exist!`);
|
|
3677
|
+
},
|
|
3678
|
+
getObjective(quest, objectiveId) {
|
|
3679
|
+
const questObjective = this.getQuest(quest).objectives[objectiveId];
|
|
3680
|
+
if (questObjective) {
|
|
3681
|
+
return questObjective;
|
|
3682
|
+
}
|
|
3683
|
+
error(`Objective ${objectiveId} doesn't exist in quest ${quest}!`);
|
|
3684
|
+
},
|
|
3685
|
+
setupQuests(quests) {
|
|
3686
|
+
// iterate through quests to generate quest states to add to this.quests object
|
|
3687
|
+
for (const key of Object.keys(quests)) {
|
|
3688
|
+
const data = quests[key];
|
|
3689
|
+
this.quests[key] = {
|
|
3690
|
+
id: key,
|
|
3691
|
+
state: 'hidden',
|
|
3692
|
+
objectives: {},
|
|
3693
|
+
};
|
|
3694
|
+
// iterate through data.objectives to populate the objectives array of this.quests[key]
|
|
3695
|
+
for (const objectiveKey of Object.keys(data.objectives)) {
|
|
3696
|
+
const objective = data.objectives[objectiveKey];
|
|
3697
|
+
this.quests[key].objectives[objectiveKey] = {
|
|
3698
|
+
id: objectiveKey,
|
|
3699
|
+
state: objective.hidden ? 'hidden' : 'unlocked',
|
|
3700
|
+
};
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
},
|
|
3704
|
+
startQuest(questId) {
|
|
3705
|
+
this.getQuest(questId).state = 'unlocked';
|
|
3706
|
+
useNotifications().addNotification(`Started quest: ${getQuestConfig(questId).title}`);
|
|
3707
|
+
},
|
|
3708
|
+
startObjective(questId, objectiveId) {
|
|
3709
|
+
this.getObjective(questId, objectiveId).state = 'unlocked';
|
|
3710
|
+
useNotifications().addNotification(`New quest objective: ${getObjectiveConfig(questId, objectiveId).description}`);
|
|
3711
|
+
},
|
|
3712
|
+
completeObjective(questId, objectiveId) {
|
|
3713
|
+
this.getObjective(questId, objectiveId).state = 'completed';
|
|
3714
|
+
useNotifications().addNotification(`Objective completed!`);
|
|
3715
|
+
},
|
|
3716
|
+
completeQuest(questId, ending) {
|
|
3717
|
+
this.getQuest(questId).state = 'completed';
|
|
3718
|
+
if (ending) {
|
|
3719
|
+
this.getQuest(questId).ending = ending;
|
|
3720
|
+
}
|
|
3721
|
+
useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
|
|
3722
|
+
},
|
|
3723
|
+
isQuestCompleted(questId) {
|
|
3724
|
+
const quest = this.getQuest(questId);
|
|
3725
|
+
return everyObject(quest.objectives, (objective) => objective.state === 'completed');
|
|
3726
|
+
},
|
|
3727
|
+
removeQuest(id) {
|
|
3728
|
+
delete this.quests[id];
|
|
3729
|
+
},
|
|
3730
|
+
generateSaveData() {
|
|
3731
|
+
return {
|
|
3732
|
+
quests: {
|
|
3733
|
+
...this.quests,
|
|
3734
|
+
},
|
|
3735
|
+
};
|
|
3736
|
+
},
|
|
3737
|
+
loadSaveData(data) {
|
|
3738
|
+
this.quests = data.quests;
|
|
3593
3739
|
},
|
|
3594
3740
|
},
|
|
3595
3741
|
});
|
|
@@ -3726,122 +3872,6 @@ var deepmerge_1 = deepmerge;
|
|
|
3726
3872
|
|
|
3727
3873
|
var cjs = deepmerge_1;
|
|
3728
3874
|
|
|
3729
|
-
// Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
|
|
3730
|
-
// setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
|
|
3731
|
-
// setStat(stat: string, value: number): Sets the value of a stat
|
|
3732
|
-
// addStat(stat: string, value: number): Adds a value to a stat
|
|
3733
|
-
// generateSaveData(): Function that generates a HudSave object from the data in the state
|
|
3734
|
-
// loadSaveData(data: HudSave): Function that loads the data into the state
|
|
3735
|
-
const useHud = pinia.defineStore('hud', {
|
|
3736
|
-
state: () => ({
|
|
3737
|
-
hudStats: {},
|
|
3738
|
-
}),
|
|
3739
|
-
actions: {
|
|
3740
|
-
setupHudStats(stats) {
|
|
3741
|
-
for (const stat in stats) {
|
|
3742
|
-
this.hudStats[stat] = {
|
|
3743
|
-
value: stats[stat].startingValue,
|
|
3744
|
-
};
|
|
3745
|
-
}
|
|
3746
|
-
},
|
|
3747
|
-
setStat(stat, value) {
|
|
3748
|
-
this.hudStats[stat].value = value;
|
|
3749
|
-
},
|
|
3750
|
-
addStat(stat, value) {
|
|
3751
|
-
this.hudStats[stat].value += value;
|
|
3752
|
-
},
|
|
3753
|
-
generateSaveData() {
|
|
3754
|
-
return {
|
|
3755
|
-
hudStats: this.hudStats,
|
|
3756
|
-
};
|
|
3757
|
-
},
|
|
3758
|
-
loadSaveData(data) {
|
|
3759
|
-
this.hudStats = cjs(this.hudStats, data.hudStats);
|
|
3760
|
-
},
|
|
3761
|
-
},
|
|
3762
|
-
});
|
|
3763
|
-
|
|
3764
|
-
// Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
|
|
3765
|
-
// addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
|
|
3766
|
-
// deleteNotification(id: string): Deletes a notification from the state
|
|
3767
|
-
const useNotifications = pinia.defineStore('notifications', {
|
|
3768
|
-
state: () => ({ notifications: {} }),
|
|
3769
|
-
actions: {
|
|
3770
|
-
async addNotification(text) {
|
|
3771
|
-
const id = `${Date.now()}-${Math.random() * 10000}`;
|
|
3772
|
-
this.notifications[id] = {
|
|
3773
|
-
text,
|
|
3774
|
-
};
|
|
3775
|
-
if (getConfig().notifications.alsoPrintInDialogue) {
|
|
3776
|
-
writeText(`[NOTIFICATION] ${text}`);
|
|
3777
|
-
}
|
|
3778
|
-
await timeout(getConfig().notifications.timeOnScreen * 1000);
|
|
3779
|
-
this.deleteNotification(id);
|
|
3780
|
-
},
|
|
3781
|
-
deleteNotification(id) {
|
|
3782
|
-
delete this.notifications[id];
|
|
3783
|
-
},
|
|
3784
|
-
},
|
|
3785
|
-
});
|
|
3786
|
-
|
|
3787
|
-
// create a pinia store named inventory with a state containing items and actions to add and delete items
|
|
3788
|
-
// create a pinia store named inventory with a state of type ItemState and actions to add and delete items. Adding items should increase the amount of any existing item that matches the id.
|
|
3789
|
-
const useInventory = pinia.defineStore('inventory', {
|
|
3790
|
-
state: () => ({
|
|
3791
|
-
items: {},
|
|
3792
|
-
}),
|
|
3793
|
-
actions: {
|
|
3794
|
-
generateSaveData() {
|
|
3795
|
-
return {
|
|
3796
|
-
items: this.items,
|
|
3797
|
-
};
|
|
3798
|
-
},
|
|
3799
|
-
loadSaveData(save) {
|
|
3800
|
-
this.items = { ...this.items, ...save.items };
|
|
3801
|
-
},
|
|
3802
|
-
setupItems(items) {
|
|
3803
|
-
Object.keys(items).forEach((key) => {
|
|
3804
|
-
this.items[key] = {
|
|
3805
|
-
amount: 0,
|
|
3806
|
-
id: key,
|
|
3807
|
-
};
|
|
3808
|
-
});
|
|
3809
|
-
},
|
|
3810
|
-
getExistingItem(id) {
|
|
3811
|
-
return this.items[id];
|
|
3812
|
-
},
|
|
3813
|
-
getItemAmount(id) {
|
|
3814
|
-
return this.getExistingItem(id)?.amount || 0;
|
|
3815
|
-
},
|
|
3816
|
-
add(item) {
|
|
3817
|
-
const existingItem = this.getExistingItem(item.id);
|
|
3818
|
-
if (existingItem) {
|
|
3819
|
-
existingItem.amount += item.amount;
|
|
3820
|
-
}
|
|
3821
|
-
else {
|
|
3822
|
-
this.items[item.id] = { ...item };
|
|
3823
|
-
}
|
|
3824
|
-
useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3825
|
-
},
|
|
3826
|
-
remove(item) {
|
|
3827
|
-
const existingItem = this.getExistingItem(item.id);
|
|
3828
|
-
if (existingItem) {
|
|
3829
|
-
existingItem.amount -= item.amount;
|
|
3830
|
-
useNotifications().addNotification(`Lost item: ${getItemConfig(item.id).name} x ${item.amount}`);
|
|
3831
|
-
if (existingItem.amount <= 0) {
|
|
3832
|
-
this.deleteItem(item.id);
|
|
3833
|
-
}
|
|
3834
|
-
}
|
|
3835
|
-
},
|
|
3836
|
-
deleteItem(id) {
|
|
3837
|
-
const existingItem = this.getExistingItem(id);
|
|
3838
|
-
if (existingItem) {
|
|
3839
|
-
this.items[id].amount = 0;
|
|
3840
|
-
}
|
|
3841
|
-
},
|
|
3842
|
-
},
|
|
3843
|
-
});
|
|
3844
|
-
|
|
3845
3875
|
// Create a pinia store named skills with a state using the type Skills, with actions:
|
|
3846
3876
|
// setupSkillCheck(skillCheck: SkillCheckState, id: string)
|
|
3847
3877
|
// passSkillCheck(skillCheckId: string)
|
|
@@ -3889,6 +3919,9 @@ const useSkills = pinia.defineStore('skills', {
|
|
|
3889
3919
|
},
|
|
3890
3920
|
addXp(skill, xp) {
|
|
3891
3921
|
const skillData = this.skills[skill];
|
|
3922
|
+
if (!skillData) {
|
|
3923
|
+
error(`Skill ${skill} doesn't exist`);
|
|
3924
|
+
}
|
|
3892
3925
|
skillData.xp += xp;
|
|
3893
3926
|
if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
|
|
3894
3927
|
skillData.xp = 0;
|
|
@@ -3929,101 +3962,6 @@ function getFile(url) {
|
|
|
3929
3962
|
});
|
|
3930
3963
|
}
|
|
3931
3964
|
|
|
3932
|
-
const everyObject = (object, predicate) => {
|
|
3933
|
-
for (const key in object) {
|
|
3934
|
-
if (!predicate(object[key])) {
|
|
3935
|
-
return false;
|
|
3936
|
-
}
|
|
3937
|
-
}
|
|
3938
|
-
return true;
|
|
3939
|
-
};
|
|
3940
|
-
const filterObject = (object, predicate) => {
|
|
3941
|
-
const result = {};
|
|
3942
|
-
for (const key in object) {
|
|
3943
|
-
if (predicate(object[key])) {
|
|
3944
|
-
result[key] = object[key];
|
|
3945
|
-
}
|
|
3946
|
-
}
|
|
3947
|
-
return result;
|
|
3948
|
-
};
|
|
3949
|
-
|
|
3950
|
-
const useQuests = pinia.defineStore('quests', {
|
|
3951
|
-
state: () => ({
|
|
3952
|
-
quests: {},
|
|
3953
|
-
}),
|
|
3954
|
-
actions: {
|
|
3955
|
-
getQuest(questId) {
|
|
3956
|
-
const quest = this.quests[questId];
|
|
3957
|
-
if (quest) {
|
|
3958
|
-
return quest;
|
|
3959
|
-
}
|
|
3960
|
-
error(`Quest ${questId} doesn't exist!`);
|
|
3961
|
-
},
|
|
3962
|
-
getObjective(quest, objectiveId) {
|
|
3963
|
-
const questObjective = this.getQuest(quest).objectives[objectiveId];
|
|
3964
|
-
if (questObjective) {
|
|
3965
|
-
return questObjective;
|
|
3966
|
-
}
|
|
3967
|
-
error(`Objective ${objectiveId} doesn't exist in quest ${quest}!`);
|
|
3968
|
-
},
|
|
3969
|
-
setupQuests(quests) {
|
|
3970
|
-
// iterate through quests to generate quest states to add to this.quests object
|
|
3971
|
-
for (const key of Object.keys(quests)) {
|
|
3972
|
-
const data = quests[key];
|
|
3973
|
-
this.quests[key] = {
|
|
3974
|
-
id: key,
|
|
3975
|
-
state: 'hidden',
|
|
3976
|
-
objectives: {},
|
|
3977
|
-
};
|
|
3978
|
-
// iterate through data.objectives to populate the objectives array of this.quests[key]
|
|
3979
|
-
for (const objectiveKey of Object.keys(data.objectives)) {
|
|
3980
|
-
const objective = data.objectives[objectiveKey];
|
|
3981
|
-
this.quests[key].objectives[objectiveKey] = {
|
|
3982
|
-
id: objectiveKey,
|
|
3983
|
-
state: objective.hidden ? 'hidden' : 'unlocked',
|
|
3984
|
-
};
|
|
3985
|
-
}
|
|
3986
|
-
}
|
|
3987
|
-
},
|
|
3988
|
-
startQuest(questId) {
|
|
3989
|
-
this.getQuest(questId).state = 'unlocked';
|
|
3990
|
-
useNotifications().addNotification(`Started quest: ${getQuestConfig(questId).title}`);
|
|
3991
|
-
},
|
|
3992
|
-
startObjective(questId, objectiveId) {
|
|
3993
|
-
this.getObjective(questId, objectiveId).state = 'unlocked';
|
|
3994
|
-
useNotifications().addNotification(`New quest objective: ${getObjectiveConfig(questId, objectiveId).description}`);
|
|
3995
|
-
},
|
|
3996
|
-
completeObjective(questId, objectiveId) {
|
|
3997
|
-
this.getObjective(questId, objectiveId).state = 'completed';
|
|
3998
|
-
useNotifications().addNotification(`Objective completed!`);
|
|
3999
|
-
},
|
|
4000
|
-
completeQuest(questId, ending) {
|
|
4001
|
-
this.getQuest(questId).state = 'completed';
|
|
4002
|
-
if (ending) {
|
|
4003
|
-
this.getQuest(questId).ending = ending;
|
|
4004
|
-
}
|
|
4005
|
-
useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
|
|
4006
|
-
},
|
|
4007
|
-
isQuestCompleted(questId) {
|
|
4008
|
-
const quest = this.getQuest(questId);
|
|
4009
|
-
return everyObject(quest.objectives, (objective) => objective.state === 'completed');
|
|
4010
|
-
},
|
|
4011
|
-
removeQuest(id) {
|
|
4012
|
-
delete this.quests[id];
|
|
4013
|
-
},
|
|
4014
|
-
generateSaveData() {
|
|
4015
|
-
return {
|
|
4016
|
-
quests: {
|
|
4017
|
-
...this.quests,
|
|
4018
|
-
},
|
|
4019
|
-
};
|
|
4020
|
-
},
|
|
4021
|
-
loadSaveData(data) {
|
|
4022
|
-
this.quests = data.quests;
|
|
4023
|
-
},
|
|
4024
|
-
},
|
|
4025
|
-
});
|
|
4026
|
-
|
|
4027
3965
|
// Create a pinia store named screens with a state using the type ScreenState, with actions:
|
|
4028
3966
|
// setScreen(screen: string): Sets the current screen to the given screen
|
|
4029
3967
|
// setButtons(buttons: { [key: string]: ButtonConfig }): Adds buttons to the buttons state by using the values in the buttons config object
|
|
@@ -4315,6 +4253,7 @@ const useVM = pinia.defineStore('vm', {
|
|
|
4315
4253
|
data: {},
|
|
4316
4254
|
lastLabel: 'main',
|
|
4317
4255
|
script: {},
|
|
4256
|
+
labelStack: ['main'],
|
|
4318
4257
|
}),
|
|
4319
4258
|
actions: {
|
|
4320
4259
|
generateSaveData() {
|
|
@@ -4431,6 +4370,19 @@ const useVM = pinia.defineStore('vm', {
|
|
|
4431
4370
|
const cmd = this.currentLine;
|
|
4432
4371
|
await runCommand(cmd);
|
|
4433
4372
|
},
|
|
4373
|
+
async runLabelFunction(label) {
|
|
4374
|
+
const branch = this.script[label];
|
|
4375
|
+
if (!branch) {
|
|
4376
|
+
console.error(`Label ${branch} doesn't exist`);
|
|
4377
|
+
}
|
|
4378
|
+
const stack = {
|
|
4379
|
+
currentIndex: 0,
|
|
4380
|
+
branch: branch,
|
|
4381
|
+
label,
|
|
4382
|
+
};
|
|
4383
|
+
this.addStack(stack);
|
|
4384
|
+
await this.runLine();
|
|
4385
|
+
},
|
|
4434
4386
|
runLabel(label) {
|
|
4435
4387
|
const branch = this.script[label];
|
|
4436
4388
|
if (!branch) {
|
|
@@ -4459,6 +4411,88 @@ const useVM = pinia.defineStore('vm', {
|
|
|
4459
4411
|
},
|
|
4460
4412
|
});
|
|
4461
4413
|
|
|
4414
|
+
function processText(text) {
|
|
4415
|
+
const vmStore = useVM();
|
|
4416
|
+
const skillStore = useSkills();
|
|
4417
|
+
return text.replace(/%{[^}]*}/g, (match) => {
|
|
4418
|
+
const key = match.substr(2, match.length - 3);
|
|
4419
|
+
const searchableState = {
|
|
4420
|
+
data: vmStore.data,
|
|
4421
|
+
skills: skillStore.skills,
|
|
4422
|
+
items: useInventory().items,
|
|
4423
|
+
quests: useQuests().quests,
|
|
4424
|
+
};
|
|
4425
|
+
const [obj, newKey] = findDataHelper(searchableState, key);
|
|
4426
|
+
return obj[newKey];
|
|
4427
|
+
});
|
|
4428
|
+
}
|
|
4429
|
+
|
|
4430
|
+
// Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
|
|
4431
|
+
const useDialogStore = pinia.defineStore('dialog', {
|
|
4432
|
+
state: () => ({
|
|
4433
|
+
dialog: [],
|
|
4434
|
+
}),
|
|
4435
|
+
actions: {
|
|
4436
|
+
generateSaveData() {
|
|
4437
|
+
return {
|
|
4438
|
+
dialog: this.dialog,
|
|
4439
|
+
};
|
|
4440
|
+
},
|
|
4441
|
+
loadSaveData(data) {
|
|
4442
|
+
this.dialog = data.dialog;
|
|
4443
|
+
},
|
|
4444
|
+
addDialog(dialog) {
|
|
4445
|
+
this.dialog.push({
|
|
4446
|
+
...dialog,
|
|
4447
|
+
interactive: dialog.interactive ?? false,
|
|
4448
|
+
id: randomId(),
|
|
4449
|
+
text: processText(dialog.text),
|
|
4450
|
+
});
|
|
4451
|
+
},
|
|
4452
|
+
clearDialog() {
|
|
4453
|
+
this.dialog.splice(0, this.dialog.length);
|
|
4454
|
+
},
|
|
4455
|
+
reset() {
|
|
4456
|
+
this.dialog = [];
|
|
4457
|
+
},
|
|
4458
|
+
},
|
|
4459
|
+
});
|
|
4460
|
+
|
|
4461
|
+
// Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
|
|
4462
|
+
// setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
|
|
4463
|
+
// setStat(stat: string, value: number): Sets the value of a stat
|
|
4464
|
+
// addStat(stat: string, value: number): Adds a value to a stat
|
|
4465
|
+
// generateSaveData(): Function that generates a HudSave object from the data in the state
|
|
4466
|
+
// loadSaveData(data: HudSave): Function that loads the data into the state
|
|
4467
|
+
const useHud = pinia.defineStore('hud', {
|
|
4468
|
+
state: () => ({
|
|
4469
|
+
hudStats: {},
|
|
4470
|
+
}),
|
|
4471
|
+
actions: {
|
|
4472
|
+
setupHudStats(stats) {
|
|
4473
|
+
for (const stat in stats) {
|
|
4474
|
+
this.hudStats[stat] = {
|
|
4475
|
+
value: stats[stat].startingValue,
|
|
4476
|
+
};
|
|
4477
|
+
}
|
|
4478
|
+
},
|
|
4479
|
+
setStat(stat, value) {
|
|
4480
|
+
this.hudStats[stat].value = value;
|
|
4481
|
+
},
|
|
4482
|
+
addStat(stat, value) {
|
|
4483
|
+
this.hudStats[stat].value += value;
|
|
4484
|
+
},
|
|
4485
|
+
generateSaveData() {
|
|
4486
|
+
return {
|
|
4487
|
+
hudStats: this.hudStats,
|
|
4488
|
+
};
|
|
4489
|
+
},
|
|
4490
|
+
loadSaveData(data) {
|
|
4491
|
+
this.hudStats = cjs(this.hudStats, data.hudStats);
|
|
4492
|
+
},
|
|
4493
|
+
},
|
|
4494
|
+
});
|
|
4495
|
+
|
|
4462
4496
|
function createSkillCheckState() {
|
|
4463
4497
|
const skillCheck = {
|
|
4464
4498
|
passed: false,
|
|
@@ -7726,22 +7760,6 @@ styleInject(css_248z$8);
|
|
|
7726
7760
|
|
|
7727
7761
|
script$7.render = render$7;
|
|
7728
7762
|
|
|
7729
|
-
function processText(text) {
|
|
7730
|
-
const vmStore = useVM();
|
|
7731
|
-
const skillStore = useSkills();
|
|
7732
|
-
return text.replace(/%{[^}]*}/g, (match) => {
|
|
7733
|
-
const key = match.substr(2, match.length - 3);
|
|
7734
|
-
const searchableState = {
|
|
7735
|
-
data: vmStore.data,
|
|
7736
|
-
skills: skillStore.skills,
|
|
7737
|
-
items: useInventory().items,
|
|
7738
|
-
quests: useQuests().quests,
|
|
7739
|
-
};
|
|
7740
|
-
const [obj, newKey] = findDataHelper(searchableState, key);
|
|
7741
|
-
return obj[newKey];
|
|
7742
|
-
});
|
|
7743
|
-
}
|
|
7744
|
-
|
|
7745
7763
|
function aspectRatioFit(screenWidth, screenHeight, gameWidth, gameHeight) {
|
|
7746
7764
|
const widthRatio = screenWidth / gameWidth;
|
|
7747
7765
|
const heightRatio = screenHeight / gameHeight;
|
|
@@ -8723,7 +8741,7 @@ var script$d = vue.defineComponent({
|
|
|
8723
8741
|
}
|
|
8724
8742
|
return {
|
|
8725
8743
|
title,
|
|
8726
|
-
text:
|
|
8744
|
+
text: dialogKey.text,
|
|
8727
8745
|
styleId: dialogKey.speaker,
|
|
8728
8746
|
choices: dialogKey.choices,
|
|
8729
8747
|
old: index < this.dialog.length - 1,
|
|
@@ -9443,6 +9461,15 @@ const completeQuestPlugin = new CommandPlugin('complete_quest', async (cmd) => {
|
|
|
9443
9461
|
return useVM().nextLine();
|
|
9444
9462
|
}, generateParser('complete_quest'));
|
|
9445
9463
|
|
|
9464
|
+
// Write a CommandPlugin for running a label using the runLabelFunction of the useVM store
|
|
9465
|
+
const runLabelPlugin = new CommandPlugin('run_label', async (cmd) => {
|
|
9466
|
+
const label = cmd.args[0];
|
|
9467
|
+
if (!label) {
|
|
9468
|
+
error(`run_label command needs a label to argument run`);
|
|
9469
|
+
}
|
|
9470
|
+
await useVM().runLabelFunction(label);
|
|
9471
|
+
}, generateParser('run_label'));
|
|
9472
|
+
|
|
9446
9473
|
function registerBaseCommands(vm) {
|
|
9447
9474
|
vm.addCommand(addItemPlugin);
|
|
9448
9475
|
vm.addCommand(addLevelPlugin);
|
|
@@ -9465,6 +9492,9 @@ function registerBaseCommands(vm) {
|
|
|
9465
9492
|
vm.addCommand(talkCommand);
|
|
9466
9493
|
vm.addCommand(textCommandPlugin);
|
|
9467
9494
|
vm.addCommand(waitCommand);
|
|
9495
|
+
// functions and labels
|
|
9496
|
+
vm.addCommand(jumpCommand);
|
|
9497
|
+
vm.addCommand(runLabelPlugin);
|
|
9468
9498
|
// Quests
|
|
9469
9499
|
vm.addCommand(startQuestPlugin);
|
|
9470
9500
|
vm.addCommand(startObjectivePlugin);
|
|
@@ -9512,7 +9542,7 @@ async function startApp(config, options) {
|
|
|
9512
9542
|
});
|
|
9513
9543
|
registerBaseCommands(vm);
|
|
9514
9544
|
logManager.setupDebugger(options.debug);
|
|
9515
|
-
console.log('%c Narrat game engine – 1.
|
|
9545
|
+
console.log('%c Narrat game engine – 1.3.0 - June 25, 2022 18:05:43', 'background: #222; color: #bada55');
|
|
9516
9546
|
vm.callHook('onNarratSetup');
|
|
9517
9547
|
app.mount('#game-holder');
|
|
9518
9548
|
if (options.debug) {
|
|
@@ -227,6 +227,7 @@ export declare const useMain: import("pinia").StoreDefinition<"main", MainState,
|
|
|
227
227
|
previousStack(): void;
|
|
228
228
|
finishGame(): void;
|
|
229
229
|
runLine(): Promise<void>;
|
|
230
|
+
runLabelFunction(label: string): Promise<void>;
|
|
230
231
|
runLabel(label: string): void;
|
|
231
232
|
}>;
|
|
232
233
|
hud: import("pinia").Store<"hud", import("./hud-stats-store").HudState, {}, {
|
package/lib/stores/vm-store.d.ts
CHANGED