summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-08-31 20:23:06 +0200
committerDaniel Weipert <code@drogueronin.de>2023-08-31 20:23:06 +0200
commitc657c77d0cf49afba627b93848e1915e2ce7d3ff (patch)
tree5d96a65df277f52558cd5ff84f2fefbf4480a926
parent7f6ab8779bd143b1b5f3465e3681abcbc113d19d (diff)
story and npcs
-rw-r--r--db/areas.php49
-rw-r--r--db/areas/mansion-basement.json5
-rw-r--r--db/areas/mansion-top-floor.json5
-rw-r--r--db/areas/mansion.json5
-rw-r--r--db/environment/mansion-basement.jpgbin0 -> 66592 bytes
-rw-r--r--db/environment/mansion-basement.json6
-rw-r--r--db/environment/mansion-main.jpgbin0 -> 101268 bytes
-rw-r--r--db/environment/mansion-main.json6
-rw-r--r--db/environment/mansion-top-floor.jpgbin0 -> 78932 bytes
-rw-r--r--db/environment/mansion-top-floor.json6
-rw-r--r--db/i18n.php19
-rw-r--r--db/i18n/de_DE.po67
-rw-r--r--db/maps/cotton-town.svg3
-rw-r--r--db/maps/dryads-grove.svg5
-rw-r--r--db/maps/leather-town.svg3
-rw-r--r--db/npc.php43
-rw-r--r--db/npc/omnichannel-ceo.json3
-rw-r--r--db/npc/tuxemart-keeper.json3
-rw-r--r--index.html1
m---------modules/tuxemon0
-rw-r--r--resources/css/menu.css4
-rw-r--r--resources/js/classes/Npc.js15
-rw-r--r--resources/js/db.js4
-rw-r--r--resources/js/game.js22
-rw-r--r--resources/js/helpers.js2
-rw-r--r--resources/js/memory.js5
-rw-r--r--resources/js/story.js38
-rw-r--r--resources/js/ui.js7
28 files changed, 274 insertions, 52 deletions
diff --git a/db/areas.php b/db/areas.php
index d2c9af9..fd0943a 100644
--- a/db/areas.php
+++ b/db/areas.php
@@ -8,16 +8,15 @@ foreach (scandir(__DIR__ . '/areas') as $file) {
$area = json_decode(file_get_contents($filePath), true);
- $encounterSlug = $area['modules/tuxemon.encounter'] ?? '';
- $encounters = json_decode(@file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/encounter/$encounterSlug.json") ?? '', true);
-
- $environmentSlug = $area['modules/tuxemon.environment'] ?? '';
- $environment = json_decode(@file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/environment/$environmentSlug.json") ?? '', true);
- $map = @file_get_contents(__DIR__ . "/maps/$fileName.svg");
+ // encounters
$area['encounters'] ??= [];
+
+ $encounterSlug = $area['modules/tuxemon.encounter'] ?? '';
+ $encounters = json_decode(@file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/encounter/$encounterSlug.json") ?? '', true);
array_push($area['encounters'], ...$encounters['monsters'] ?? []);
+
if (! empty($area['encounters'])) {
// filter out duplicates, because day/night is ignored for now
$duplicates = [];
@@ -34,16 +33,38 @@ foreach (scandir(__DIR__ . '/areas') as $file) {
}
$area['encounter_percent_total'] = array_sum(array_column($area['encounters'], 'encounter_percent'));
}
+
$area['requiredEncounters'] ??= 0;
+
+ // trainers
+
$area['trainers'] ??= [];
+
+ // environment
+
+ $environmentSlug = $area['modules/tuxemon.environment'] ?? '';
+ $environment = json_decode(@file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/environment/$environmentSlug.json") ?? '', true);
+
+ if (isset($area['environment'])) {
+ $environment = json_decode(file_get_contents(__DIR__ . "/environment/$area[environment].json"), true);
+ $environment['battle_graphics']['background'] = '/db/environment/' . $environment['battle_graphics']['background'];
+ } else if (! empty($environment)) {
+ $environment['battle_graphics']['background'] = '/modules/tuxemon/mods/tuxemon/gfx/ui/combat/' . $environment['battle_graphics']['background'];
+ }
+
$area['environment'] = $environment;
+
+
+ // map
+
+ $map = @file_get_contents(__DIR__ . "/maps/$fileName.svg");
+
$area['map'] = $map;
- foreach ($area['connections'] as $areaSlug => $connection) {
- $area['connections'][$areaSlug]['modules/tuxemon.slug'] = json_decode(@file_get_contents(__DIR__ . "/areas/$areaSlug.json") ?? '', true)['modules/tuxemon.slug'] ?? '';
- }
+
+ // locations
$area['locations'] ??= [];
foreach ($area['locations'] as $locationId => $location) {
@@ -54,5 +75,15 @@ foreach (scandir(__DIR__ . '/areas') as $file) {
}
}
+
+ // connections
+
+ foreach ($area['connections'] as $areaSlug => $connection) {
+ $area['connections'][$areaSlug]['modules/tuxemon.slug'] = json_decode(@file_get_contents(__DIR__ . "/areas/$areaSlug.json") ?? '', true)['modules/tuxemon.slug'] ?? '';
+ }
+
+
+ // build
+
file_put_contents(__DIR__ . "/_generated/areas/$fileName.json", json_encode($area));
}
diff --git a/db/areas/mansion-basement.json b/db/areas/mansion-basement.json
index 1a90497..14ea293 100644
--- a/db/areas/mansion-basement.json
+++ b/db/areas/mansion-basement.json
@@ -29,6 +29,8 @@
}
],
+ "environment": "mansion-basement",
+
"connections": {
"mansion": {
"conditions": []
@@ -36,6 +38,5 @@
},
"modules/tuxemon.slug": "mansion_basement",
- "modules/tuxemon.encounter": "mansion",
- "modules/tuxemon.environment": "cave"
+ "modules/tuxemon.encounter": "mansion"
}
diff --git a/db/areas/mansion-top-floor.json b/db/areas/mansion-top-floor.json
index 02bf87e..4f92836 100644
--- a/db/areas/mansion-top-floor.json
+++ b/db/areas/mansion-top-floor.json
@@ -61,6 +61,8 @@
}
],
+ "environment": "mansion-top-floor",
+
"connections": {
"mansion": {
"conditions": []
@@ -68,6 +70,5 @@
},
"modules/tuxemon.slug": "mansion_top_floor",
- "modules/tuxemon.encounter": "mansion",
- "modules/tuxemon.environment": "cave"
+ "modules/tuxemon.encounter": "mansion"
}
diff --git a/db/areas/mansion.json b/db/areas/mansion.json
index 82de65a..aed6ead 100644
--- a/db/areas/mansion.json
+++ b/db/areas/mansion.json
@@ -18,6 +18,8 @@
}
],
+ "environment": "mansion-main",
+
"connections": {
"side-route-a": {
"conditions": []
@@ -37,6 +39,5 @@
},
"modules/tuxemon.slug": "mansion",
- "modules/tuxemon.encounter": "mansion",
- "modules/tuxemon.environment": "cave"
+ "modules/tuxemon.encounter": "mansion"
}
diff --git a/db/environment/mansion-basement.jpg b/db/environment/mansion-basement.jpg
new file mode 100644
index 0000000..2aa4546
--- /dev/null
+++ b/db/environment/mansion-basement.jpg
Binary files differ
diff --git a/db/environment/mansion-basement.json b/db/environment/mansion-basement.json
new file mode 100644
index 0000000..87d5412
--- /dev/null
+++ b/db/environment/mansion-basement.json
@@ -0,0 +1,6 @@
+{
+ "battle_graphics": {
+ "background": "mansion-basement.jpg",
+ "background_position": "center"
+ }
+}
diff --git a/db/environment/mansion-main.jpg b/db/environment/mansion-main.jpg
new file mode 100644
index 0000000..eef40df
--- /dev/null
+++ b/db/environment/mansion-main.jpg
Binary files differ
diff --git a/db/environment/mansion-main.json b/db/environment/mansion-main.json
new file mode 100644
index 0000000..cc5503e
--- /dev/null
+++ b/db/environment/mansion-main.json
@@ -0,0 +1,6 @@
+{
+ "battle_graphics": {
+ "background": "mansion-main.jpg",
+ "background_position": "bottom"
+ }
+}
diff --git a/db/environment/mansion-top-floor.jpg b/db/environment/mansion-top-floor.jpg
new file mode 100644
index 0000000..8fb45cc
--- /dev/null
+++ b/db/environment/mansion-top-floor.jpg
Binary files differ
diff --git a/db/environment/mansion-top-floor.json b/db/environment/mansion-top-floor.json
new file mode 100644
index 0000000..870e1af
--- /dev/null
+++ b/db/environment/mansion-top-floor.json
@@ -0,0 +1,6 @@
+{
+ "battle_graphics": {
+ "background": "mansion-top-floor.jpg",
+ "background_position": "center"
+ }
+}
diff --git a/db/i18n.php b/db/i18n.php
index 0942802..b4f7cbc 100644
--- a/db/i18n.php
+++ b/db/i18n.php
@@ -10,12 +10,23 @@ function populateI18n ($locale, $poFile) {
while ($line = fgets($handle)) {
if (str_starts_with($line, 'msgid')) {
$nextLine = fgets($handle);
- preg_match('/"(.*)"/', $line, $msgid);
- preg_match('/"(.*)"/', $nextLine, $msgstr);
+ preg_match('/"(.*)"/', $line, $msgidMatch);
+ preg_match('/"(.*)"/', $nextLine, $msgstrMatch);
- if (empty($msgid[1]) || str_starts_with($msgid[1], 'PROJECT DESCRIPTION')) continue;
+ if (empty($msgidMatch[1]) || str_starts_with($msgidMatch[1], 'PROJECT DESCRIPTION')) continue;
+ $msgid = $msgidMatch[1];
- $i18n[$locale][$msgid[1]] = mb_convert_encoding($msgstr[1], 'UTF-8');
+ // get lines immediately after msgstr
+ $msgstr = $msgstrMatch[1];
+ $msgstrNextLine = fgets($handle);
+ while (! empty(trim($msgstrNextLine))) {
+ preg_match('/"(.*)"/', $msgstrNextLine, $msgstrNextLineMatch);
+ $msgstr .= $msgstrNextLineMatch[1];
+
+ $msgstrNextLine = fgets($handle);
+ }
+
+ $i18n[$locale][$msgid] = mb_convert_encoding($msgstr, 'UTF-8');
}
}
}
diff --git a/db/i18n/de_DE.po b/db/i18n/de_DE.po
index 8fdc013..90b97bb 100644
--- a/db/i18n/de_DE.po
+++ b/db/i18n/de_DE.po
@@ -175,3 +175,70 @@ msgstr "Wähle dein Tuxemon!"
msgid "story:select_starter_monster:monster_selection:title"
msgstr "Wähle dein tatsächliches Tuxemon!"
+
+
+
+
+# modules/tuxemon
+
+
+# Routes
+
+msgid "dryadsgrove"
+msgstr "Nymphenhain"
+
+msgid "routea"
+msgstr "Route A"
+
+msgid "routec"
+msgstr "Route C"
+
+
+# Story
+
+msgid "spyder_intro00"
+msgstr "Hallo! Ich bin der CEO von Omnichannel. Wir betreiben die Zeitungen, Fernsehsender und Radio Stationen in dieser Region.\n"
+"Es ist meine Pflicht euch zu informieren."
+
+msgid "spyder_intro01"
+msgstr "Tuxemon sind die Tiere, die in dieser Welt leben.\n"
+"Sie lieben es gefangen zu werden, sodass ihre Meister sie für Spaß und Profit kämpfen lassen können.\n"
+"Die stärksten gewinnen, genau wie in der Welt der Unternehmen.\n"
+"Die meisten Monster lassen sich in der Wildnis finden. Sie entwickeln sich weiter, wenn sie Erfahrung sammeln.\n"
+"Aber die fünf Säulen, die die Kathedrale formen, also, die fünf allierten Firmen, die in dieser Region agieren,\n"
+"haben die Natur verbessert. Diese Saison bietet wir fünf deluxe Tuxemon an!"
+
+msgid "spyder_intro_shopkeeper1"
+msgstr "Was für eine großartige Präsentation von unserem CEO! Alle Gold Mitglieder bekommen ein kostenloses Tuxemon geboten."
+
+msgid "spyder_intro_shopkeeper4"
+msgstr "Tut mir Leid, aber du bist kein Gold Mitglied. Dieses Angebot gilt nur für Gold Mitlieder."
+
+msgid "spyder_papertown_myfirstmon_notmet"
+msgstr "Ich erkenne dich wieder! Du bist das Kind, das keinen Gold Pass hat.\n"
+"Weißt du, ich könnte dir vielleicht helfen.\n"
+"Als die neuen schmucken Tuxemon von der Kathedrale kamen, haben wir einfach alle alten in den Müll geschmissen!\n"
+"Das fühlt sich nach so einer Verschwendung an, besonders wenn Kinder wie du keine haben!"
+
+msgid "spyder_papertown_myfirstmon1"
+msgstr "*wühl* *wühl*"
+
+msgid "spyder_papertown_myfirstmon2"
+msgstr "Sieht aus als wären Tuxemon in den meisten Mülltonnen. \n Mein Chef hat mich gerufen. Viel Glück!"
+
+msgid "spyder_papertown_firstfight"
+msgstr "Hey, warum wühlst du in den Mülltonnen rum? Das ist eklig - und es ist gegen die Regeln!\n"
+"...\n"
+"Was? Es wurden komplett normale Tuxemon weggeworfen?\n"
+"...\n"
+"Nun, wenn sie keine Mängel gehabt hätten, wären sie bestimmt nicht weggeworfen worden.\n"
+"Sie müssen im Vergleich zu den neuen Modellen minderwertig sein. Hier, ich zeige es dir!"
+
+msgid "spyder_papertown_firstfight_win"
+msgstr "Hmm, das war wohl Glück. Unmöglich, dass das neue Model schlechter als das alte ist!"
+
+msgid "spyder_papertown_firstfight_lose"
+msgstr "War zu erwarten! Alte Modelle können sich nicht mit neuen vergleichen!"
+
+msgid "spyder_papertown_firstfight_after"
+msgstr "Dieses mal heile ich deine Tuxemon, aber ich bin nicht die Wohlfahrt. Ruht euch das nächste Mal zu Hause aus, wenn deine Monster erschöpft sind."
diff --git a/db/maps/cotton-town.svg b/db/maps/cotton-town.svg
index d2d7314..0137fb1 100644
--- a/db/maps/cotton-town.svg
+++ b/db/maps/cotton-town.svg
@@ -5,9 +5,6 @@
>
<image href="/db/maps/Cotton_town.png" />
- <text x="275" y="445">Healing Center</text>
<rect data-location="healing_center" x="288" y="368" width="80" height="64" stroke="red" fill="transparent" />
-
- <text x="470" y="573">Shop</text>
<rect data-location="cotton_scoop" x="448" y="496" width="80" height="64" stroke="red" fill="transparent" />
</svg>
diff --git a/db/maps/dryads-grove.svg b/db/maps/dryads-grove.svg
index ada9703..09a5f29 100644
--- a/db/maps/dryads-grove.svg
+++ b/db/maps/dryads-grove.svg
@@ -5,5 +5,8 @@
>
<image href="/db/maps/Dryads_Grove.png" />
- <rect data-encounter="volcoli" data-encounter-level="55" x="544" y="207" width="16" height="16" stroke="red" fill="transparent" />
+ <rect
+ data-encounter="volcoli" data-encounter-level="55"
+ data-interactable="true"
+ x="544" y="207" width="16" height="16" stroke="red" fill="transparent" />
</svg>
diff --git a/db/maps/leather-town.svg b/db/maps/leather-town.svg
index 9607b32..f131896 100644
--- a/db/maps/leather-town.svg
+++ b/db/maps/leather-town.svg
@@ -5,9 +5,6 @@
>
<image href="/db/maps/Leather_Town.png" />
- <text x="323" y="174">Healing Center</text>
<rect data-location="healing_center" x="336" y="97" width="80" height="64" stroke="red" fill="transparent" />
-
- <text x="226" y="174">Shop</text>
<rect data-location="leather_scoop" x="208" y="97" width="80" height="64" stroke="red" fill="transparent" />
</svg>
diff --git a/db/npc.php b/db/npc.php
new file mode 100644
index 0000000..4aabc8a
--- /dev/null
+++ b/db/npc.php
@@ -0,0 +1,43 @@
+<?php
+
+$npcs = [];
+
+// modules/tuxemon
+$basePath = dirname(__DIR__) . '/modules/tuxemon/mods/tuxemon/db/npc';
+foreach (scandir($basePath) as $fileName) {
+ if (in_array($fileName, ['.', '..'])) continue;
+
+ $filePath = "$basePath/$fileName";
+ $json = json_decode(file_get_contents($filePath), true);
+
+ if (isset($json['slug']) && isset($json['template'])) {
+ $npcs[$json['slug']] = $json;
+ } else {
+ foreach ($json as $npc) {
+ $npcs[$npc['slug']] = $npc;
+ }
+ }
+}
+
+// tuxemon clicker
+$basePath = __DIR__ . '/npc';
+foreach (scandir($basePath) as $fileName) {
+ if (in_array($fileName, ['.', '..'])) continue;
+
+ $filePath = "$basePath/$fileName";
+ $npc = json_decode(file_get_contents($filePath), true);
+
+ $slug = $npc['modules/tuxemon.slug'] ?? pathinfo($fileName, PATHINFO_FILENAME);
+ $npcs[$slug] = [
+ 'slug' => $slug,
+ 'template' => [
+ [
+ 'sprite_name' => $npc['sprite'],
+ ],
+ ],
+ ];
+}
+
+foreach ($npcs as $slug => $npc) {
+ file_put_contents(__DIR__ . "/_generated/npc/$slug.json", json_encode($npc));
+}
diff --git a/db/npc/omnichannel-ceo.json b/db/npc/omnichannel-ceo.json
new file mode 100644
index 0000000..818098a
--- /dev/null
+++ b/db/npc/omnichannel-ceo.json
@@ -0,0 +1,3 @@
+{
+ "sprite": "ceo"
+}
diff --git a/db/npc/tuxemart-keeper.json b/db/npc/tuxemart-keeper.json
new file mode 100644
index 0000000..1779fbd
--- /dev/null
+++ b/db/npc/tuxemart-keeper.json
@@ -0,0 +1,3 @@
+{
+ "sprite": "shopassist"
+}
diff --git a/index.html b/index.html
index 8b284c2..e2950ac 100644
--- a/index.html
+++ b/index.html
@@ -422,6 +422,7 @@
<script type="text/javascript" src="/resources/js/classes/StatusEffect.js"></script>
<script type="text/javascript" src="/resources/js/classes/Item.js"></script>
<script type="text/javascript" src="/resources/js/classes/InventoryItem.js"></script>
+ <script type="text/javascript" src="/resources/js/classes/Npc.js"></script>
<script type="text/javascript" src="/resources/js/classes/Area.js"></script>
<script type="text/javascript" src="/resources/js/classes/State.js"></script>
<script type="text/javascript" src="/resources/js/db.js"></script>
diff --git a/modules/tuxemon b/modules/tuxemon
-Subproject 136c50bff1fb5b04a1cb0032030fb868c0bca9e
+Subproject 068b9c44345a86e83b35383a2e372629214f51f
diff --git a/resources/css/menu.css b/resources/css/menu.css
index 56e2525..70fc0b8 100644
--- a/resources/css/menu.css
+++ b/resources/css/menu.css
@@ -386,6 +386,7 @@
border: 2px solid yellow !important;
}
+.setting-highlight--map svg [data-interactable],
.setting-highlight--map svg [data-location],
.setting-highlight--map svg [data-area],
.setting-highlight--map svg [data-encounter] {
@@ -425,7 +426,8 @@
.story__popup {
padding: 1rem;
- max-width: 300px;
+ max-width: 100vw;
+ width: 360px;
display: grid;
grid-gap: 1rem;
diff --git a/resources/js/classes/Npc.js b/resources/js/classes/Npc.js
new file mode 100644
index 0000000..6121bce
--- /dev/null
+++ b/resources/js/classes/Npc.js
@@ -0,0 +1,15 @@
+class Npc {
+ name = '';
+ spriteName = '';
+
+ constructor (slug) {
+ this.slug = slug;
+
+ this.name = translate(slug) || slugToName(slug.replace('spyder_', ''));
+ this.spriteName = DB.npcs[slug]?.template[0].sprite_name;
+ }
+
+ get sprite () {
+ return `/modules/tuxemon/mods/tuxemon/gfx/sprites/player/${this.spriteName}.png`;
+ }
+}
diff --git a/resources/js/db.js b/resources/js/db.js
index 3c8be05..35ed7bd 100644
--- a/resources/js/db.js
+++ b/resources/js/db.js
@@ -171,10 +171,10 @@ async function fetchItem (slug) {
*/
async function fetchNpc (slug) {
if (! DB.npcs[slug]) {
- DB.npcs[slug] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/npc/${slug}.json`).then((response) => response.json());
+ DB.npcs[slug] = await fetchDBData(`/db/_generated/npc/${slug}.json`).then((response) => response.json());
}
- return DB.npcs[slug];
+ return new Npc(slug);
}
/**
diff --git a/resources/js/game.js b/resources/js/game.js
index fb25ea4..2c6ecc0 100644
--- a/resources/js/game.js
+++ b/resources/js/game.js
@@ -26,6 +26,7 @@ const Game = {
isProgressingTurn: false,
playerIsChoosingNextMonster: false,
isStoryBattle: false,
+ didWinStoryBattle: true,
doBattleAnimation: true,
opponentActionTimeout: null,
didTechniqueHit: false,
@@ -127,6 +128,7 @@ const Game = {
UI.showMap();
}
+ Game.didWinStoryBattle = true;
Game.isStoryBattle = false;
} else {
await Game.encounterNextTrainerMonster();
@@ -151,6 +153,7 @@ const Game = {
// whole party defeated
if (!Memory.state.player.monsters.some((monster) => monster.hp > 0)) {
Memory.state.Game.isInBattle = false;
+ Game.didWinStoryBattle = false;
Game.isStoryBattle = false;
if (Memory.state.currentArea.monsterProgress < Memory.state.currentArea.requiredEncounters) {
@@ -161,16 +164,10 @@ const Game = {
await Game.goToArea(Memory.state.lastVisitedTown);
// heal all monsters full
- let totalHealingCenterPrice = 0;
- for (const monster of Memory.state.player.monsters) {
- monster.hp = monster.stats.hp;
- monster.statusEffect = null;
-
- // pay healing center
- const healingCenterPrice = Object.values(Memory.state.currentArea.locations).find((location) => location.type === 'healingCenter').price;
- totalHealingCenterPrice += healingCenterPrice;
- }
+ Game.healParty();
+ const healingCenterPrice = Object.values(Memory.state.currentArea.locations).find((location) => location.type === 'healingCenter').price;
+ const totalHealingCenterPrice = healingCenterPrice * Memory.state.player.monsters.length;
Memory.state.money -= totalHealingCenterPrice;
Game.addPhaseEvent('postTurnEnd', () => {
@@ -1006,6 +1003,13 @@ const Game = {
monster.evolve(monster.evolutions[0]);
},
+ healParty () {
+ for (const monster of Memory.state.player.monsters) {
+ monster.hp = monster.stats.hp;
+ monster.statusEffect = null;
+ }
+ },
+
/**
* @param {string} type
*
diff --git a/resources/js/helpers.js b/resources/js/helpers.js
index bceaf5e..aa149b1 100644
--- a/resources/js/helpers.js
+++ b/resources/js/helpers.js
@@ -19,7 +19,7 @@ function slugToName (slug) {
* @returns {string}
*/
function nl2br (text) {
- return text.replace(new RegExp(/\\n/g), '<br>');
+ return text.replace(new RegExp(/\\n/g), '<br><br>');
}
/**
diff --git a/resources/js/memory.js b/resources/js/memory.js
index f8d8a82..47608da 100644
--- a/resources/js/memory.js
+++ b/resources/js/memory.js
@@ -251,12 +251,11 @@ const Memory = {
UI.drawArea();
UI.drawStatus();
},
-
-
- async () => Story.progress(Memory.state.currentStory),
];
await UI.showLoading(loadActions);
+
+ await Story.progress(Memory.state.currentStory)
},
/**
diff --git a/resources/js/story.js b/resources/js/story.js
index bdec2e1..1901829 100644
--- a/resources/js/story.js
+++ b/resources/js/story.js
@@ -10,10 +10,14 @@ const Story = {
}));
});
- await Story.progress('introduction');
+ await Story.immediateProgress('start', 'introduction');
},
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 possibleStarterMonsters = await Promise.all(
[
'budaye',
@@ -37,7 +41,7 @@ const Story = {
event.detail.popup.remove();
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_dante'), text: translate('spyder_intro_shopkeeper4', true) });
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('tuxemart-keeper'), text: translate('spyder_intro_shopkeeper4', true) });
// set rival monster
Memory.state.rivalMonster = event.detail.monster.slug;
@@ -55,6 +59,7 @@ 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 possibleStarterMonsters = await Promise.all(
@@ -93,7 +98,7 @@ const Story = {
}));
});
- await Story.progress('battleRivalOne');
+ await Story.immediateProgress('selectStarterMonster', 'battleRivalOne');
},
async battleRivalOne () {
@@ -102,9 +107,18 @@ const Story = {
Memory.state.opponent = new Trainer({ monsters: [ rivalMonster ] });
await Memory.state.opponent.initialize();
- await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_rivalbillie'), text: translate('spyder_papertown_firstfight', true) });
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight', true) });
await Story.battle();
+
+ if (Game.didWinStoryBattle) {
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_win', true) });
+ } else {
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_lose', true) });
+ }
+
+ await UI.buildAndShowStoryPopup({ speaker: await fetchNpc('spyder_billie'), text: translate('spyder_papertown_firstfight_after', true) });
+ Game.healParty();
},
@@ -112,8 +126,6 @@ const Story = {
/**
* @param {string} slug
- *
- * @returns {Promise<any>}
*/
async progress (slug) {
if (!Story[slug]) {
@@ -131,8 +143,16 @@ const Story = {
},
/**
- * @returns {Promise<any>}
+ * @param {string} fromSlug
+ * @param {string} toSlug
*/
+ async immediateProgress (fromSlug, toSlug) {
+ Memory.state.storyProgress[fromSlug] = true;
+ Memory.saveToLocalStorage();
+
+ await Story.progress(toSlug);
+ },
+
async battle () {
const previousArea = Object.assign({}, Memory.state.currentArea);
@@ -152,6 +172,10 @@ const Story = {
}, 100);
});
+ // reset incremented trainer progress
+ if (Memory.state.areaProgress[previousArea.slug]) {
+ Memory.state.areaProgress[previousArea.slug].trainerProgress = previousArea.trainerProgress;
+ }
if (previousArea.slug === Memory.state.currentArea.slug) {
Memory.state.currentArea.trainerProgress = previousArea.trainerProgress;
diff --git a/resources/js/ui.js b/resources/js/ui.js
index 6884e14..e5afb53 100644
--- a/resources/js/ui.js
+++ b/resources/js/ui.js
@@ -556,7 +556,8 @@ const UI = {
},
drawBattle () {
- UI.elements.battle.style.backgroundImage = `url(/modules/tuxemon/mods/tuxemon/gfx/ui/combat/${Memory.state.currentArea.environment.battle_graphics.background})`;
+ UI.elements.battle.style.backgroundImage = `url(${Memory.state.currentArea.environment.battle_graphics.background})`;
+ UI.elements.battle.style.backgroundPosition = `${Memory.state.currentArea.environment.battle_graphics.background_position || 'top'}`;
UI.showBattle();
UI.drawOpponentMonster();
@@ -1945,8 +1946,8 @@ const UI = {
applyStoryPopupContent (popup, { speaker, text }) {
const template = UI.createTemplate(Template.storyPopup);
- template.querySelector('[data-template-slot="speaker.sprite"]').src = `/modules/tuxemon/mods/tuxemon/gfx/sprites/player/${speaker.template[0].sprite_name}.png`;
- template.querySelector('[data-template-slot="speaker.name"]').textContent = slugToName(speaker.slug.replace('spyder_', ''));
+ template.querySelector('[data-template-slot="speaker.sprite"]').src = speaker.sprite;
+ template.querySelector('[data-template-slot="speaker.name"]').textContent = speaker.name;
template.querySelector('[data-template-slot="text"]').innerHTML = nl2br(text);
template.querySelector('[data-template-slot="next"]').addEventListener('click', UI.wrapCallback(() => {
popup.dispatchEvent(new Event('next'));