<q:application id="rpg" type="game">

  <!-- RPG: Godot's "JRPG" demo (godotengine/godot-demo-projects, 2d/role_playing_game,
       MIT), transcribed. A slime walks a grassy map cell by cell, reads a key,
       talks to another slime and fights it, turn by turn: Attack, Defend, Flee.
       The art and the font are the demo's (assets/LICENSE.md), packed by
       scripts/art/rpg.py; README.md says what is where. -->

  <!-- How the last fight ended ('' before any), and the cell it was started from. -->
  <q:set name="outcome" value="" />
  <q:set name="back_col" value="3" type="number" />
  <q:set name="back_row" value="4" type="number" />
  <!-- Beyond the demo: what the player carries, and what it took from the map, by name. -->
  <q:set name="keys" value="0" type="number" />
  <q:set name="potions" value="0" type="number" />
  <q:set name="taken" value="[]" type="array" />

  <!-- The demo's ui_accept: Enter, Space, the joypad's A; and a click. -->
  <qg:input action="select" keys="Enter, Space, MouseLeft, JoyA" />

  <!-- Every tile of the three layers is a picture of its own; the Grid
       layer's are the ones that stop a walker. -->
  <!-- beyond the demo: the game in Portuguese and Spanish (a web page's ?lang=pt, the command line's q-lang, or the system's language) -->
    <!-- on a phone: what the keys do, under a finger, in every scene -->
  <qg:touch-stick x="140" y="580" size="200" />

  <qg:language lang="pt" name="Português">
    <qg:phrase text="Hey, it's a good time to have a JRPG fight, right?" as="Ei, é uma boa hora para uma luta de JRPG, não acha?" />
    <qg:phrase text="Let me introduce myself, I'm your OPPONENT." as="Deixa eu me apresentar: sou o seu OPONENTE." />
    <qg:phrase text="Enough talking. Let's fight!" as="Chega de conversa. Vamos lutar!" />
    <qg:phrase text="Just a key..." as="Só uma chave..." />
    <qg:phrase text="I'll keep it anyway." as="Vou guardar mesmo assim." />
    <qg:phrase text="A potion! In a fight, it gives back 5 life." as="Uma poção! Numa luta, ela devolve 5 de vida." />
    <qg:phrase text="Congratulations, you won!" as="Parabéns, você venceu!" />
    <qg:phrase text="Aha! I won, maybe you can try again next time." as="Rá! Eu venci, quem sabe você tenta de novo outra vez." />
    <qg:phrase text="UNKNOWN" as="DESCONHECIDO" />
    <qg:phrase text="OPPONENT" as="OPONENTE" />
    <qg:phrase text="PLAYER" as="JOGADOR" />
    <qg:phrase text="Player" as="Jogador" />
    <qg:phrase text="Opponent" as="Oponente" />
    <qg:phrase text="Attack" as="Atacar" />
    <qg:phrase text="Defend" as="Defender" />
    <qg:phrase text="Potion" as="Poção" />
    <qg:phrase text="Flee" as="Fugir" />
      <qg:phrase text="Resume" as="Continuar" />
    <qg:phrase text="Music" as="Música" />
    <qg:phrase text="Full screen" as="Tela cheia" />
    <qg:phrase text="on" as="sim" />
    <qg:phrase text="off" as="não" />
    <qg:phrase text="potion" as="poção" />
    <qg:phrase text="potions" as="poções" />
    <qg:phrase text="key" as="chave" />
    <qg:phrase text="keys" as="chaves" />
    <!-- the fight's banner, drawn in Portuguese -->
    <qg:asset name="banner" src="assets/banner-pt.png" />
</qg:language>
  <qg:language lang="es" name="Español">
    <qg:phrase text="Hey, it's a good time to have a JRPG fight, right?" as="Oye, es un buen momento para una pelea de JRPG, ¿no crees?" />
    <qg:phrase text="Let me introduce myself, I'm your OPPONENT." as="Déjame presentarme: soy tu OPONENTE." />
    <qg:phrase text="Enough talking. Let's fight!" as="Basta de charla. ¡A pelear!" />
    <qg:phrase text="Just a key..." as="Solo una llave..." />
    <qg:phrase text="I'll keep it anyway." as="Me la quedo de todos modos." />
    <qg:phrase text="A potion! In a fight, it gives back 5 life." as="¡Una poción! En una pelea, devuelve 5 de vida." />
    <qg:phrase text="Congratulations, you won!" as="¡Felicidades, ganaste!" />
    <qg:phrase text="Aha! I won, maybe you can try again next time." as="¡Ajá! Gané, tal vez puedas intentarlo de nuevo la próxima vez." />
    <qg:phrase text="UNKNOWN" as="DESCONOCIDO" />
    <qg:phrase text="OPPONENT" as="OPONENTE" />
    <qg:phrase text="PLAYER" as="JUGADOR" />
    <qg:phrase text="Player" as="Jugador" />
    <qg:phrase text="Opponent" as="Oponente" />
    <qg:phrase text="Attack" as="Atacar" />
    <qg:phrase text="Defend" as="Defender" />
    <qg:phrase text="Potion" as="Poción" />
    <qg:phrase text="Flee" as="Huir" />
      <qg:phrase text="Resume" as="Continuar" />
    <qg:phrase text="Music" as="Música" />
    <qg:phrase text="Full screen" as="Pantalla completa" />
    <qg:phrase text="on" as="sí" />
    <qg:phrase text="off" as="no" />
    <qg:phrase text="potion" as="poción" />
    <qg:phrase text="potions" as="pociones" />
    <qg:phrase text="key" as="llave" />
    <qg:phrase text="keys" as="llaves" />
    <qg:asset name="banner" src="assets/banner-es.png" />
</qg:language>
  <!-- Russian: letters Montserrat has not, so a font that has them (Xolonium, assets/LICENSE.md),
       and three plural forms: 1 зелье, 2 зелья, 5 зелий -->
  <qg:language lang="ru" name="Русский" font="assets/Xolonium-Regular.ttf">
    <qg:phrase text="Hey, it's a good time to have a JRPG fight, right?" as="Эй, самое время для JRPG-драки, правда?" />
    <qg:phrase text="Let me introduce myself, I'm your OPPONENT." as="Позволь представиться: я твой ПРОТИВНИК." />
    <qg:phrase text="Enough talking. Let's fight!" as="Хватит болтать. В бой!" />
    <qg:phrase text="Just a key..." as="Просто ключ..." />
    <qg:phrase text="I'll keep it anyway." as="Всё равно возьму." />
    <qg:phrase text="A potion! In a fight, it gives back 5 life." as="Зелье! В бою оно возвращает 5 жизни." />
    <qg:phrase text="Congratulations, you won!" as="Поздравляю, ты победил!" />
    <qg:phrase text="Aha! I won, maybe you can try again next time." as="Ага! Я победил. Может, в следующий раз получится." />
    <qg:phrase text="UNKNOWN" as="НЕЗНАКОМЕЦ" />
    <qg:phrase text="OPPONENT" as="ПРОТИВНИК" />
    <qg:phrase text="PLAYER" as="ИГРОК" />
    <qg:phrase text="Player" as="Игрок" />
    <qg:phrase text="Opponent" as="Противник" />
    <qg:phrase text="Attack" as="Атака" />
    <qg:phrase text="Defend" as="Защита" />
    <qg:phrase text="Potion" as="Зелье" />
    <qg:phrase text="Flee" as="Бежать" />
    <qg:phrase text="Resume" as="Продолжить" />
    <qg:phrase text="Music" as="Музыка" />
    <qg:phrase text="Full screen" as="Полный экран" />
    <qg:phrase text="on" as="вкл" />
    <qg:phrase text="off" as="выкл" />
    <qg:phrase text="potion" as="зелье" />
    <qg:phrase text="potions" as="зелий" one="зелье" few="зелья" />
    <qg:phrase text="key" as="ключ" />
    <qg:phrase text="keys" as="ключей" one="ключ" few="ключа" />
    <qg:asset name="banner" src="assets/banner-ru.png" />
</qg:language>

  <qg:tileset name="world" src="assets/tiles.png" tile="64" />
  <qg:spritesheet name="pawns" src="assets/pawns.png" tile="64" />
  <qg:spritesheet name="fighters" src="assets/fighters.png" tile="128" />
  <qg:spritesheet name="arena" src="assets/arena.png" tile="1280x720" />
  <!-- beyond the demo: a frame for the dialogue box that stretches to it (its 16-pixel edges stay as drawn),
       and "FIGHT!" as the fight starts, drawn in each language (scripts/art/rpg_extra.py, CC0) -->
  <qg:spritesheet name="frame" src="assets/frame.png" tile="48" slice="16" />
  <qg:spritesheet name="banner" src="assets/banner-en.png" tile="480x120" />
  <qg:prefab name="Banner" tag="banner" sheet="banner" hitbox="480x120" />
  <!-- beyond the demo: music of our own (scripts/art/rpg_music.py, CC0) -->
  <qg:sound bus="music" name="meadow" src="assets/meadow.ogg" loop="true" />
  <qg:sound bus="music" name="clash" src="assets/clash.ogg" loop="true" />

  <qg:prefab name="Opponent" tag="opponent" sheet="pawns" frame="2" hitbox="48x48" />
  <qg:prefab name="Key" tag="key" sheet="pawns" frame="3" hitbox="48x48" />
  <qg:prefab name="Potion" tag="potion" sheet="pawns" frame="4" hitbox="48x48" />

  <!-- ===== Exploration: grid_movement/exploration.tscn ===== -->

  <qg:scene name="exploration" width="1280" height="720" background="#62a033">
    <qg:music sound="meadow" fade="0.6" volume="-4" />
    <qg:tilemap tileset="world">
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    </qg:tilemap>
    <qg:tilemap tileset="world">
0,0,0,0,0,0,0,0,0,0,0,2,3,3,3,4,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,5,6,6,6,7,0,0,0,0
0,0,8,9,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,11,12,4,0,0,13,13,13,13,10,0,0,0,0,0,0,0,0
0,0,11,12,14,0,0,15,15,15,15,14,0,0,0,0,0,0,0,0
0,0,5,16,7,0,0,6,6,6,6,17,0,0,0,8,13,13,12,0
0,0,0,0,0,0,0,0,0,0,0,18,13,19,0,20,12,12,12,0
0,0,0,0,0,0,0,0,0,0,0,20,21,14,0,22,12,12,12,12
0,0,0,0,0,0,0,0,0,0,0,5,23,17,0,24,23,23,12,12
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    </qg:tilemap>
    <qg:tilemap tileset="world" collision="true">
25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,28
29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,0,31,28
29,0,0,0,0,0,32,33,33,33,34,0,0,0,0,0,0,0,31,28
29,0,0,0,0,0,31,25,26,26,35,0,0,0,0,0,0,32,36,28
29,0,0,0,0,0,31,29,0,0,0,0,0,0,0,0,0,37,38,28
29,0,0,0,0,0,31,39,33,33,34,0,0,0,0,0,0,40,27,28
29,41,0,0,0,0,40,42,26,26,35,0,0,0,0,0,0,0,31,28
43,44,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,28
28,28,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,36,28
28,28,43,44,44,44,44,34,0,0,0,0,0,0,0,0,0,37,38,28
28,28,28,28,28,28,28,43,44,44,44,44,44,44,44,44,44,36,38,28
    </qg:tilemap>

    <qg:instance prefab="Key" name="key" x="544" y="288" if="{'key' not in taken}" />
    <qg:instance prefab="Potion" name="potion-1" x="96" y="96" if="{'potion-1' not in taken}" />
    <qg:instance prefab="Potion" name="potion-2" x="928" y="608" if="{'potion-2' not in taken}" />
    <qg:instance prefab="Opponent" x="800" y="480" />

    <qg:character id="player" controller="grid" diagonal="true" step-frames="15"
                  sheet="pawns" frame="0" x="224" y="288" hitbox="48x48">
      <qg:animation name="idle" frames="0" fps="1" />
      <qg:animation name="walk" frames="0" fps="1" />
      <qg:animation name="bump" frames="1" fps="1" />
      <qg:on-collision with="key">
        <q:set name="taken" value="{taken + [other.name]}" />
        <q:set name="keys" value="{keys + 1}" />
        <qg:destroy target="other" />
        <qg:say dialogue="key" />
      </qg:on-collision>
      <qg:on-collision with="potion">
        <q:set name="taken" value="{taken + [other.name]}" />
        <q:set name="potions" value="{potions + 1}" />
        <qg:destroy target="other" />
        <qg:say dialogue="potion" />
      </qg:on-collision>
      <qg:on-collision with="opponent">
        <q:set name="back_col" value="{me.col}" />
        <q:set name="back_row" value="{me.row}" />
        <qg:say dialogue="npc" />
      </qg:on-collision>
    </qg:character>

    <!-- dialogue/dialogue_data/*.json -->
    <qg:dialogue name="npc" font="assets/montserrat_extra_bold.otf" size="28" box="frame">
      <qg:line who="UNKNOWN" text="Hey, it's a good time to have a JRPG fight, right?" />
      <qg:line who="UNKNOWN" text="Let me introduce myself, I'm your OPPONENT." />
      <qg:line who="OPPONENT" text="Enough talking. Let's fight!" />
      <qg:on-end>
        <qg:goto-scene name="combat" fade="0.4" />
      </qg:on-end>
    </qg:dialogue>
    <qg:dialogue name="key" font="assets/montserrat_extra_bold.otf" size="28" box="frame">
      <qg:line who="PLAYER" text="Just a key..." />
      <qg:line who="PLAYER" text="I'll keep it anyway." />
    </qg:dialogue>
    <qg:dialogue name="potion" font="assets/montserrat_extra_bold.otf" size="28" box="frame">
      <qg:line who="PLAYER" text="A potion! In a fight, it gives back 5 life." />
    </qg:dialogue>

    <!-- What the player carries. -->
    <!-- beyond the demo: "1 potion", "2 potions", in the player's language and its plural forms -->
    <qg:hud position="top-left" font="assets/montserrat_extra_bold.otf" size="24">
      <qg:text value="{str(potions) + ' ' + tr_n('potion', 'potions', potions)}" />
      <qg:text value="{str(keys) + ' ' + tr_n('key', 'keys', keys)}" />
    </qg:hud>
    <qg:dialogue name="won" font="assets/montserrat_extra_bold.otf" size="28" box="frame">
      <qg:line who="OPPONENT" text="Congratulations, you won!" />
      <qg:on-end><q:set name="outcome" value="" /></qg:on-end>
    </qg:dialogue>
    <qg:dialogue name="lost" font="assets/montserrat_extra_bold.otf" size="28" box="frame">
      <qg:line who="OPPONENT" text="Aha! I won, maybe you can try again next time." />
      <qg:on-end><q:set name="outcome" value="" /></qg:on-end>
    </qg:dialogue>

    <!-- beyond the demo: Escape (or the joypad's B) pauses, with the options; not while someone talks -->
    <qg:on-input action="cancel">
      <q:if condition="{not talking()}">
        <q:if condition="{paused()}"><qg:resume /><q:else><qg:pause /></q:else></q:if>
      </q:if>
    </qg:on-input>
    <qg:menu if="{paused() and not talking()}" size="32">
      <qg:button label="Resume"><qg:resume /></qg:button>
      <qg:slider label="Music" bus="music" />
      <qg:button label="{tr('Full screen') + ': ' + (tr('on') if fullscreen() else tr('off'))}"><qg:fullscreen /></qg:button>
    </qg:menu>

    <!-- Back from a fight: where it started, and what the opponent says of it. -->
    <q:if condition="{outcome != ''}">
      <qg:put target="player" x="{back_col * 64 + 32}" y="{back_row * 64 + 32}" />
      <q:if condition="{outcome == 'won'}"><qg:say dialogue="won" /></q:if>
      <q:if condition="{outcome == 'lost'}"><qg:say dialogue="lost" /></q:if>
    </q:if>
  </qg:scene>

  <!-- ===== Combat: combat/combat.tscn, turn_queue.gd, combatant.gd, health.gd ===== -->

  <qg:scene name="combat" width="1280" height="720" background="#4a4a4a">
    <qg:music sound="clash" fade="0.4" volume="-6" />
    <!-- player.tscn: 10 life, 2 damage, 1 defense, 1 base armor;
         opponent.tscn: 7 life, 3 damage, 1 defense, no armor. -->
    <q:set name="life" value="10" type="number" />
    <q:set name="armor" value="1" type="number" />
    <q:set name="foe_life" value="7" type="number" />
    <q:set name="foe_armor" value="0" type="number" />
    <q:set name="turn" value="player" />
    <q:set name="wait" value="0" type="number" />   <!-- the opponent's Timer: 0.25 s -->
    <!-- beyond the demo: a fighter just hit makes a face for half a second -->
    <q:set name="hurt" value="0" type="number" />
    <q:set name="foe_hurt" value="0" type="number" />

    <!-- health.gd: a hit takes the damage less the armor. -->
    <q:function name="end" params="result">
      <q:set name="outcome" value="{result}" />
      <qg:goto-scene name="exploration" fade="0.4" />
    </q:function>
    <q:function name="foes_turn">
      <q:set name="turn" value="opponent" />
      <q:if condition="{foe_armor >= 0 + 1}"><q:set name="foe_armor" value="0" /></q:if>
      <q:set name="wait" value="15" />
    </q:function>

    <qg:sprite sheet="arena" x="640" y="360" />
    <qg:sprite sheet="fighters" frame="4" x="440" y="470" />
    <qg:sprite sheet="fighters" frame="4" x="840" y="470" />
    <qg:sprite sheet="fighters" frame="{1 if hurt > 0 else 0}" x="440" y="420" />
    <qg:sprite sheet="fighters" frame="{3 if foe_hurt > 0 else 2}" x="840" y="420" />
    <!-- beyond the demo: FIGHT! (in the player's language) as the scene fades in, and gone a second later -->
    <qg:instance prefab="Banner" name="banner" x="640" y="250" />
    <qg:timer after="60">
      <qg:tween target="banner" property="alpha" to="0" seconds="0.5">
        <qg:on-end><qg:destroy target="me" /></qg:on-end>
      </qg:tween>
    </qg:timer>

    <qg:hud position="top-left" font="assets/montserrat_extra_bold.otf" size="32">
      <qg:text value="{'Player'}" />
      <qg:bar bind="life" max="10" width="320" height="20" color="#d81b60" />
    </qg:hud>
    <qg:hud position="top-right" font="assets/montserrat_extra_bold.otf" size="32">
      <qg:text value="{'Opponent'}" />
      <qg:bar bind="foe_life" max="7" width="320" height="20" color="#d81b60" />
    </qg:hud>

    <!-- ui.gd: the buttons work on the player's turn; beyond the demo, in the dialogues' frame. -->
    <qg:menu position="bottom-center" font="assets/montserrat_extra_bold.otf" size="36" box="frame"
             if="{turn == 'player'}">
      <qg:button label="Attack">
        <q:set name="foe_life" value="{foe_life - 2 + foe_armor}" />
        <q:set name="foe_hurt" value="30" />
        <qg:shake frames="10" strength="6" />
        <q:if condition="{foe_life <= 0}"><q:call function="end" args="'won'" /></q:if>
        <q:if condition="{foe_life > 0}"><q:call function="foes_turn" /></q:if>
      </qg:button>
      <qg:button label="Defend">
        <q:set name="armor" value="{armor + 1}" />
        <q:call function="foes_turn" />
      </qg:button>
      <!-- beyond the demo: a potion gives back 5 life (health.gd's heal, up to the most) -->
      <qg:button label="Potion" if="{potions > 0}">
        <q:set name="potions" value="{potions - 1}" />
        <q:set name="life" value="{min(10, life + 5)}" />
        <q:call function="foes_turn" />
      </qg:button>
      <qg:button label="Flee">
        <q:call function="end" args="'lost'" />
      </qg:button>
    </qg:menu>

    <!-- opponent.gd: a quarter of a second into its turn, it attacks. -->
    <qg:timer every="1">
      <q:if condition="{hurt > 0}"><q:set name="hurt" value="{hurt - 1}" /></q:if>
      <q:if condition="{foe_hurt > 0}"><q:set name="foe_hurt" value="{foe_hurt - 1}" /></q:if>
      <q:if condition="{turn == 'opponent' and wait > 0}">
        <q:set name="wait" value="{wait - 1}" />
        <q:if condition="{wait == 0}">
          <q:set name="life" value="{life - 3 + armor}" />
          <q:set name="hurt" value="30" />
          <qg:shake frames="10" strength="6" />
          <q:if condition="{life <= 0}"><q:call function="end" args="'lost'" /></q:if>
          <q:if condition="{life > 0}">
            <q:set name="turn" value="player" />
            <q:if condition="{armor >= 1 + 1}"><q:set name="armor" value="1" /></q:if>
          </q:if>
        </q:if>
      </q:if>
    </qg:timer>
  </qg:scene>

</q:application>
