summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-09-01 21:40:11 +0200
committerDaniel Weipert <code@drogueronin.de>2023-09-01 21:40:11 +0200
commit6b3a8aef783368d0ed9a2c104eea3ff5cf9984da (patch)
tree7da1f4a6ad2bc0d549579678900eaf9c9a3f572f
parent94cf76f8968cf81a06d70fe329b5edf4ec07f94f (diff)
story as json in db
-rw-r--r--db/story/battle-rival-one.json19
-rw-r--r--db/story/introduction.json46
-rw-r--r--db/story/select-starter-monster.json35
-rw-r--r--resources/js/db.js60
-rw-r--r--resources/js/definitions.js1
-rw-r--r--resources/js/story.js90
6 files changed, 205 insertions, 46 deletions
diff --git a/db/story/battle-rival-one.json b/db/story/battle-rival-one.json
new file mode 100644
index 0000000..499b01d
--- /dev/null
+++ b/db/story/battle-rival-one.json
@@ -0,0 +1,19 @@
+{
+ "characters": {
+ "rival": {
+ "slug": "spyder_billie",
+ "text": [
+ "spyder_papertown_firstfight",
+ "spyder_papertown_firstfight_win",
+ "spyder_papertown_firstfight_lose",
+ "spyder_papertown_firstfight_after"
+ ],
+ "monsters": [
+ {
+ "slug": "RIVAL",
+ "level": 5
+ }
+ ]
+ }
+ }
+}
diff --git a/db/story/introduction.json b/db/story/introduction.json
new file mode 100644
index 0000000..7fa2ea3
--- /dev/null
+++ b/db/story/introduction.json
@@ -0,0 +1,46 @@
+{
+ "characters": {
+ "ceo": {
+ "slug": "omnichannel-ceo",
+ "text": [
+ "spyder_intro00",
+ "spyder_intro01"
+ ]
+ },
+
+ "shopKeeper": {
+ "slug": "tuxemart-keeper",
+ "text": [
+ "spyder_intro_shopkeeper1",
+ "spyder_intro_shopkeeper4"
+ ]
+ }
+ },
+
+ "monsters": [
+ {
+ "slug": "budaye",
+ "level": 5
+ },
+ {
+ "slug": "dollfin",
+ "level": 5
+ },
+ {
+ "slug": "grintot",
+ "level": 5
+ },
+ {
+ "slug": "ignibus",
+ "level": 5
+ },
+ {
+ "slug": "memnomnom",
+ "level": 5
+ }
+ ],
+
+ "money": 250,
+
+ "area": "paper-town"
+}
diff --git a/db/story/select-starter-monster.json b/db/story/select-starter-monster.json
new file mode 100644
index 0000000..017a284
--- /dev/null
+++ b/db/story/select-starter-monster.json
@@ -0,0 +1,35 @@
+{
+ "characters": {
+ "dante": {
+ "slug": "spyder_dante",
+ "text": [
+ "spyder_papertown_myfirstmon_notmet",
+ "spyder_papertown_myfirstmon1",
+ "spyder_papertown_myfirstmon2"
+ ]
+ }
+ },
+
+ "monsters": [
+ {
+ "slug": "tweesher",
+ "level": 5
+ },
+ {
+ "slug": "lambert",
+ "level": 5
+ },
+ {
+ "slug": "nut",
+ "level": 5
+ },
+ {
+ "slug": "agnite",
+ "level": 5
+ },
+ {
+ "slug": "rockitten",
+ "level": 5
+ }
+ ]
+}
diff --git a/resources/js/db.js b/resources/js/db.js
index 35ed7bd..6e53b7e 100644
--- a/resources/js/db.js
+++ b/resources/js/db.js
@@ -4,6 +4,21 @@
* @property {string} monster_slug
* @property {string} at_level
* @property {string} item
+ *
+ * @typedef {Object} DB_NPC
+ * @property {string} slug
+ * @property {Object[]} template
+ * @property {string} template[].sprite_name
+ *
+ * @typedef {Object} DB_Story
+ * @property {number} money
+ * @property {string} area
+ * @property {Object<string, DB_StoryCharacter>} characters
+ *
+ * @typedef {Object} DB_StoryCharacter
+ * @property {string} slug
+ * @property {string[]} text
+ * @property {Object[]} monsters
*/
//
@@ -64,17 +79,37 @@ const DB = {
/**
* @typedef {Object} DB_Item
*
- * @type {Object.<string, DB_Item>}
+ * @type {Object.<ItemSlug, DB_Item>}
*/
items: {},
+ /**
+ * @typedef {Object} DB_NPC
+ *
+ * @type {Object.<string, DB_NPC>}
+ */
npcs: {},
+ /**
+ * @typedef {Object} DB_Area
+ *
+ * @type {Object.<AreaSlug, DB_Area>}
+ */
areas: {},
+ /**
+ * @type {Object.<StorySlug, DB_Story>}
+ */
+ story: {},
+
+ /**
+ * @typedef {string} DB_Translation
+ *
+ * @type {Object.<string, DB_Translation>}
+ */
translations: {},
- currencies : {},
+ currencies: {},
};
async function initializeDB () {
@@ -152,7 +187,7 @@ async function fetchStatusEffect (slug) {
}
/**
- * @param {string} slug
+ * @param {ItemSlug} slug
*
* @returns {Promise<Item>}
*/
@@ -167,7 +202,7 @@ async function fetchItem (slug) {
/**
* @param {string} slug
*
- * @returns {Promise<Object>}
+ * @returns {Promise<Npc>}
*/
async function fetchNpc (slug) {
if (! DB.npcs[slug]) {
@@ -178,9 +213,22 @@ async function fetchNpc (slug) {
}
/**
+ * @param {StorySlug} slug
+ *
+ * @returns {Promise<DB_Story>}
+ */
+async function fetchStory (slug) {
+ if (! DB.story[slug]) {
+ DB.story[slug] = await fetchDBData(`/db/story/${slug}.json`).then((response) => response.json());
+ }
+
+ return DB.story[slug];
+}
+
+/**
* @param {string} locale
*
- * @returns {Promise<Object>}
+ * @returns {Promise<DB_Translation>}
*/
async function fetchTranslation (locale) {
if (! DB.translations[locale]) {
@@ -191,7 +239,7 @@ async function fetchTranslation (locale) {
}
/**
- * @param {string} slug
+ * @param {AreaSlug} slug
*
* @returns {Promise<Area>}
*/
diff --git a/resources/js/definitions.js b/resources/js/definitions.js
index f39025d..25f55f2 100644
--- a/resources/js/definitions.js
+++ b/resources/js/definitions.js
@@ -3,6 +3,7 @@
* @typedef {string} TechniqueSlug
* @typedef {string} ItemSlug
* @typedef {string} AreaSlug
+ * @typedef {string} StorySlug
*/
//
diff --git a/resources/js/story.js b/resources/js/story.js
index 1901829..0ceb224 100644
--- a/resources/js/story.js
+++ b/resources/js/story.js
@@ -14,20 +14,20 @@ const Story = {
},
async introduction () {
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('omnichannel-ceo'), text: translate('spyder_intro00', true) });
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('omnichannel-ceo'), text: translate('spyder_intro01', true) });
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('tuxemart-keeper'), text: translate('spyder_intro_shopkeeper1', true) });
+ const story = await fetchStory('introduction');
+ const characterCeo = story.characters.ceo;
+ const characterShopKeeper = story.characters.shopKeeper;
+ const npcCeo = await fetchNpc(characterCeo.slug);
+ const npcShopKeeper = await fetchNpc(characterShopKeeper.slug);
+
+ await UI.buildAndShowStoryPopup({ speaker: npcCeo, text: translate(characterCeo.text[0], true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcCeo, text: translate(characterCeo.text[1], true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcShopKeeper, text: translate(characterShopKeeper.text[0], true) });
const possibleStarterMonsters = await Promise.all(
- [
- 'budaye',
- 'dollfin',
- 'grintot',
- 'ignibus',
- 'memnomnom',
- ].map(async (monsterSlug) => {
- const monster = await fetchMonster(monsterSlug);
- monster.level = 5;
+ story.monsters.map(async (monsterData) => {
+ const monster = await fetchMonster(monsterData.slug);
+ monster.level = monsterData.level;
return monster;
})
);
@@ -41,16 +41,16 @@ const Story = {
event.detail.popup.remove();
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('tuxemart-keeper'), text: translate('spyder_intro_shopkeeper4', true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcShopKeeper, text: translate(characterShopKeeper.text[1], true) });
// set rival monster
Memory.state.rivalMonster = event.detail.monster.slug;
// set initial values
- Memory.state.money = 250;
+ Memory.state.money = story.money;
// go to starting area
- await Game.goToArea('paper-town');
+ await Game.goToArea(story.area);
resolve();
}));
@@ -58,20 +58,18 @@ const Story = {
},
async selectStarterMonster () {
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_papertown_myfirstmon_notmet', true) });
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_papertown_myfirstmon1', true) });
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_papertown_myfirstmon2', true) });
+ const story = await fetchStory('select-starter-monster');
+ const characterDante = story.characters.dante;
+ const npcDante = await fetchNpc(characterDante.slug);
+
+ await UI.buildAndShowStoryPopup({ speaker: npcDante, text: translate(characterDante.text[0], true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcDante, text: translate(characterDante.text[1], true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcDante, text: translate(characterDante.text[2], true) });
const possibleStarterMonsters = await Promise.all(
- [
- 'tweesher',
- 'lambert',
- 'nut',
- 'agnite',
- 'rockitten',
- ].map(async (monsterSlug) => {
- const monster = await fetchMonster(monsterSlug);
- monster.level = 5;
+ story.monsters.map(async (monsterData) => {
+ const monster = await fetchMonster(monsterData.slug);
+ monster.level = monsterData.level;
return monster;
})
);
@@ -86,9 +84,6 @@ const Story = {
Memory.state.player.monsters.push(event.detail.monster);
Game.setActivePlayerMonster(event.detail.monster);
- // go to starting area
- await Game.goToArea('paper-town');
-
UI.drawActiveMonster();
UI.drawActiveTechniques();
@@ -102,22 +97,37 @@ const Story = {
},
async battleRivalOne () {
- const rivalMonster = await fetchMonster(Memory.state.rivalMonster);
- rivalMonster.level = 5;
- Memory.state.opponent = new Trainer({ monsters: [ rivalMonster ] });
+ const story = await fetchStory('battle-rival-one');
+ const characterRival = story.characters.rival;
+ const npcRival = await fetchNpc(story.characters.rival.slug);
+
+ Memory.state.opponent = new Trainer({
+ monsters: await Promise.all(
+ characterRival.monsters.map(async (monsterData) => {
+ if (monsterData.slug === 'RIVAL') {
+ monsterData.slug = Memory.state.rivalMonster;
+ }
+
+ const monster = await fetchMonster(monsterData.slug);
+ monster.level = monsterData.level;
+
+ return monster;
+ })
+ )
+ });
await Memory.state.opponent.initialize();
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight', true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcRival, text: translate(characterRival.text[0], true) });
await Story.battle();
if (Game.didWinStoryBattle) {
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_win', true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcRival, text: translate(characterRival.text[1], true) });
} else {
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_lose', true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcRival, text: translate(characterRival.text[2], true) });
}
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_after', true) });
+ await UI.buildAndShowStoryPopup({ speaker: npcRival, text: translate(characterRival.text[3], true) });
Game.healParty();
},
@@ -125,7 +135,7 @@ const Story = {
// Helper
/**
- * @param {string} slug
+ * @param {StorySlug} slug
*/
async progress (slug) {
if (!Story[slug]) {
@@ -143,8 +153,8 @@ const Story = {
},
/**
- * @param {string} fromSlug
- * @param {string} toSlug
+ * @param {StorySlug} fromSlug
+ * @param {StorySlug} toSlug
*/
async immediateProgress (fromSlug, toSlug) {
Memory.state.storyProgress[fromSlug] = true;