Merge branch 'master' of ssh://git.devraza.giize.com:2222/atiran/sovereignx
This commit is contained in:
commit
cd52a5c018
18 changed files with 1583 additions and 568 deletions
|
@ -1,52 +0,0 @@
|
|||
name: ⚔️ Battle Engine mechanical bugs 🐛
|
||||
description: File a bug report related to battle mechanic, be it moves, abilities and/or items.
|
||||
labels: ["bug", "status: unconfirmed", "category: battle-mechanic"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill in all required fields with as many details as possible.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Describe the issue you are experiencing.
|
||||
Attach images/videos if possible.
|
||||
placeholder: |
|
||||
Please enter a description of the issue. Here you can also attach log screenshots, gifs or a video
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of pokeemerald-expansion are you using as a base?
|
||||
options:
|
||||
- 1.10.1 (Latest release)
|
||||
- master (default, unreleased bugfixes)
|
||||
- upcoming (Edge)
|
||||
- 1.10.0
|
||||
- 1.9.4
|
||||
- 1.9.3
|
||||
- 1.9.2
|
||||
- 1.9.1
|
||||
- 1.9.0
|
||||
- pre-1.9.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: upcomingversion
|
||||
attributes:
|
||||
label: Upcoming/master Version
|
||||
description: If you're using the upcoming or master branches directly, please specify what was the commit hash you pulled from.
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Discord contact info
|
||||
description: Provide your Discord tag here so we can contact you in case we need more details. Be sure to join our server ([here](https://discord.gg/6CzjAG6GZk)).
|
||||
placeholder: ex. Lunos#4026
|
||||
validations:
|
||||
required: false
|
52
.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml
vendored
52
.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml
vendored
|
@ -1,52 +0,0 @@
|
|||
name: 🧠 Battle AI bugs 🐛
|
||||
description: File a bug report related to battle AI.
|
||||
labels: ["bug", "status: unconfirmed", "category: battle-ai"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill in all required fields with as many details as possible.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Describe the issue you are experiencing.
|
||||
Attach images/videos if possible.
|
||||
placeholder: |
|
||||
Please enter a description of the issue. Here you can also attach log screenshots, gifs or a video
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of pokeemerald-expansion are you using as a base?
|
||||
options:
|
||||
- 1.10.1 (Latest release)
|
||||
- master (default, unreleased bugfixes)
|
||||
- upcoming (Edge)
|
||||
- 1.10.0
|
||||
- 1.9.4
|
||||
- 1.9.3
|
||||
- 1.9.2
|
||||
- 1.9.1
|
||||
- 1.9.0
|
||||
- pre-1.9.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: upcomingversion
|
||||
attributes:
|
||||
label: Upcoming/master Version
|
||||
description: If you're using the upcoming or master branches directly, please specify what was the commit hash you pulled from.
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Discord contact info
|
||||
description: Provide your Discord tag here so we can contact you in case we need more details. Be sure to join our server ([here](https://discord.gg/6CzjAG6GZk)).
|
||||
placeholder: ex. Lunos#4026
|
||||
validations:
|
||||
required: false
|
27
.github/ISSUE_TEMPLATE/03_feature_requests.yaml
vendored
27
.github/ISSUE_TEMPLATE/03_feature_requests.yaml
vendored
|
@ -1,27 +0,0 @@
|
|||
name: 🙏 Feature Request 🙏
|
||||
description: Do you want a feature to be added to the Expansion? Let us know!
|
||||
labels: ["feature-request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill in all required fields with as many details as possible.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Describe the issue you are experiencing.
|
||||
Attach images/videos if possible.
|
||||
placeholder: |
|
||||
Please enter a description of the issue. Here you can also attach log screenshots, gifs or a video
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Discord contact info
|
||||
description: Provide your Discord tag here so we can contact you in case we need more details. Be sure to join our server ([here](https://discord.gg/6CzjAG6GZk)).
|
||||
placeholder: ex. Lunos#4026
|
||||
validations:
|
||||
required: false
|
52
.github/ISSUE_TEMPLATE/04_other_errors.yaml
vendored
52
.github/ISSUE_TEMPLATE/04_other_errors.yaml
vendored
|
@ -1,52 +0,0 @@
|
|||
name: 💾 Other errors 🖥️
|
||||
description: Everything else that doesn't fit in the above categories.
|
||||
labels: ["bug", "status: unconfirmed"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill in all required fields with as many details as possible.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Describe the issue you are experiencing.
|
||||
Attach images/videos if possible.
|
||||
placeholder: |
|
||||
Please enter a description of the issue. Here you can also attach log screenshots, gifs or a video
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of pokeemerald-expansion are you using as a base?
|
||||
options:
|
||||
- 1.10.1 (Latest release)
|
||||
- master (default, unreleased bugfixes)
|
||||
- upcoming (Edge)
|
||||
- 1.10.0
|
||||
- 1.9.4
|
||||
- 1.9.3
|
||||
- 1.9.2
|
||||
- 1.9.1
|
||||
- 1.9.0
|
||||
- pre-1.9.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: upcomingversion
|
||||
attributes:
|
||||
label: Upcoming/master Version
|
||||
description: If you're using the upcoming or master branches directly, please specify what was the commit hash you pulled from.
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Discord contact info
|
||||
description: Provide your Discord tag here so we can contact you in case we need more details. Be sure to join our server ([here](https://discord.gg/6CzjAG6GZk)).
|
||||
placeholder: ex. Lunos#4026
|
||||
validations:
|
||||
required: false
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,5 +0,0 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Rom-Hacking Hideout's Discord server!
|
||||
url: https://discord.gg/6CzjAG6GZk
|
||||
about: You can follow the development of pokeemerald-expansion and be notified of new releases :)
|
175
.github/calcrom/calcrom.pl
vendored
175
.github/calcrom/calcrom.pl
vendored
|
@ -1,175 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Usage:
|
||||
# calcrom.pl <mapfile> [--data]
|
||||
#
|
||||
# mapfile: path to .map file output by LD
|
||||
# data: set to output % breakdown of data
|
||||
|
||||
use IPC::Cmd qw[ run ];
|
||||
use Getopt::Long;
|
||||
|
||||
my $usage = "Usage: calcrom.pl file.map [--data]\n";
|
||||
|
||||
my $showData;
|
||||
GetOptions("data" => \$showData) or die $usage;
|
||||
|
||||
(@ARGV == 1)
|
||||
or die $usage;
|
||||
open(my $file, $ARGV[0])
|
||||
or die "ERROR: could not open file '$ARGV[0]'.\n";
|
||||
|
||||
my $src = 0;
|
||||
my $asm = 0;
|
||||
my $srcdata = 0;
|
||||
my $data = 0;
|
||||
while (my $line = <$file>)
|
||||
{
|
||||
if ($line =~ /^ \.(\w+)\s+0x[0-9a-f]+\s+(0x[0-9a-f]+) (\w+)\/.+\.o/)
|
||||
{
|
||||
my $section = $1;
|
||||
my $size = hex($2);
|
||||
my $dir = $3;
|
||||
|
||||
if ($section =~ /text/)
|
||||
{
|
||||
if ($dir eq 'src')
|
||||
{
|
||||
$src += $size;
|
||||
}
|
||||
elsif ($dir eq 'asm')
|
||||
{
|
||||
$asm += $size;
|
||||
}
|
||||
}
|
||||
elsif ($section =~ /rodata/)
|
||||
{
|
||||
if ($dir eq 'src')
|
||||
{
|
||||
$srcdata += $size;
|
||||
}
|
||||
elsif ($dir eq 'data')
|
||||
{
|
||||
$data += $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(my $elffname = $ARGV[0]) =~ s/\.map/.elf/;
|
||||
|
||||
# Note that the grep filters out all branch labels. It also requires a minimum
|
||||
# line length of 5, to filter out a ton of generated symbols (like AcCn). No
|
||||
# settings to nm seem to remove these symbols. Finally, nm prints out a separate
|
||||
# entry for whenever a name appears in a file, not just where it's defined. uniq
|
||||
# removes all the duplicate entries.
|
||||
#
|
||||
#
|
||||
# You'd expect this to take a while, because of uniq. It runs in under a second,
|
||||
# though. Uniq is pretty fast!
|
||||
my $base_cmd = "nm $elffname | awk '{print \$3}' | grep '^[^_].\\{4\\}' | uniq";
|
||||
|
||||
# This looks for Unknown_, Unknown_, or sub_, followed by an address. Note that
|
||||
# it matches even if stuff precedes the unknown, like sUnknown/gUnknown.
|
||||
my $undoc_regex = "'[Uu]nknown_[0-9a-fA-F]\\{5,7\\}\\|sub_[0-9a-fA-F]\\{5,7\\}'";
|
||||
|
||||
# This looks for every symbol with an address at the end of it. Some things are
|
||||
# given a name based on their type / location, but still have an unknown purpose.
|
||||
# For example, FooMap_EventScript_FFFFFFF.
|
||||
# The above may be double counted here, and will need to be filtered out.
|
||||
my $partial_doc_regex = "'_[0-28][0-9a-fA-F]\\{5,7\\}'";
|
||||
|
||||
my $count_cmd = "wc -l";
|
||||
|
||||
# It sucks that we have to run this three times, but I can't figure out how to get
|
||||
# stdin working for subcommands in perl while still having a timeout. It's decently
|
||||
# fast anyway.
|
||||
my $total_syms_as_string;
|
||||
(run (
|
||||
command => "$base_cmd | $count_cmd",
|
||||
buffer => \$total_syms_as_string,
|
||||
timeout => 60
|
||||
))
|
||||
or die "ERROR: Error while getting all symbols: $?";
|
||||
|
||||
my $undocumented_as_string;
|
||||
(run (
|
||||
command => "$base_cmd | grep $undoc_regex | $count_cmd",
|
||||
buffer => \$undocumented_as_string,
|
||||
timeout => 60
|
||||
))
|
||||
or die "ERROR: Error while filtering for undocumented symbols: $?";
|
||||
|
||||
my $partial_documented_as_string;
|
||||
(run (
|
||||
command => "$base_cmd | grep $partial_doc_regex | grep -v $undoc_regex | $count_cmd",
|
||||
buffer => \$partial_documented_as_string,
|
||||
timeout => 60
|
||||
))
|
||||
or die "ERROR: Error while filtering for partial symbols: $?";
|
||||
|
||||
# Performing addition on a string converts it to a number. Any string that fails
|
||||
# to convert to a number becomes 0. So if our converted number is 0, but our string
|
||||
# is nonzero, then the conversion was an error.
|
||||
$undocumented_as_string =~ s/^\s+|\s+$//g;
|
||||
my $undocumented = $undocumented_as_string + 0;
|
||||
(($undocumented != 0) or (($undocumented == 0) and ($undocumented_as_string eq "0")))
|
||||
or die "ERROR: Cannot convert string to num: '$undocumented_as_string'";
|
||||
|
||||
$partial_documented_as_string =~ s/^\s+|\s+$//g;
|
||||
my $partial_documented = $partial_documented_as_string + 0;
|
||||
(($partial_documented != 0) or (($partial_documented == 0) and ($partial_documented_as_string eq "0")))
|
||||
or die "ERROR: Cannot convert string to num: '$partial_documented_as_string'";
|
||||
|
||||
$total_syms_as_string =~ s/^\s+|\s+$//g;
|
||||
my $total_syms = $total_syms_as_string + 0;
|
||||
(($total_syms != 0) or (($total_syms == 0) and ($total_syms_as_string eq "0")))
|
||||
or die "ERROR: Cannot convert string to num: '$total_syms_as_string'";
|
||||
|
||||
($total_syms != 0)
|
||||
or die "ERROR: No symbols found.";
|
||||
|
||||
my $total = $src + $asm;
|
||||
my $srcPct = sprintf("%.4f", 100 * $src / $total);
|
||||
my $asmPct = sprintf("%.4f", 100 * $asm / $total);
|
||||
|
||||
my $documented = $total_syms - ($undocumented + $partial_documented);
|
||||
my $docPct = sprintf("%.4f", 100 * $documented / $total_syms);
|
||||
my $partialPct = sprintf("%.4f", 100 * $partial_documented / $total_syms);
|
||||
my $undocPct = sprintf("%.4f", 100 * $undocumented / $total_syms);
|
||||
|
||||
if ($asm == 0)
|
||||
{
|
||||
print "Code decompilation is 100% complete\n"
|
||||
}
|
||||
else
|
||||
{
|
||||
print "$total total bytes of code\n";
|
||||
print "$src bytes of code in src ($srcPct%)\n";
|
||||
print "$asm bytes of code in asm ($asmPct%)\n";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
if ($partial_documented == 0 && $undocumented == 0)
|
||||
{
|
||||
print "Documentation is 100% complete\n"
|
||||
}
|
||||
else
|
||||
{
|
||||
print "$total_syms total symbols\n";
|
||||
print "$documented symbols documented ($docPct%)\n";
|
||||
print "$partial_documented symbols partially documented ($partialPct%)\n";
|
||||
print "$undocumented symbols undocumented ($undocPct%)\n";
|
||||
}
|
||||
|
||||
if ($showData)
|
||||
{
|
||||
print "\n";
|
||||
my $dataTotal = $srcdata + $data;
|
||||
my $srcDataPct = sprintf("%.4f", 100 * $srcdata / $dataTotal);
|
||||
my $dataPct = sprintf("%.4f", 100 * $data / $dataTotal);
|
||||
|
||||
print "$dataTotal total bytes of data\n";
|
||||
print "$srcdata bytes of data in src ($srcDataPct%)\n";
|
||||
print "$data bytes of data in data ($dataPct%)\n";
|
||||
}
|
11
.github/calcrom/webhook.sh
vendored
11
.github/calcrom/webhook.sh
vendored
|
@ -1,11 +0,0 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
build_name=$1
|
||||
map_file=$build_name.map
|
||||
if [ ! -f $map_file ]; then
|
||||
echo "$map_file does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
output=$(perl $(dirname "$0")/calcrom.pl $build_name.map | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g')
|
||||
curl -d "{\"username\": \"$CALCROM_DISCORD_WEBHOOK_USERNAME\", \"avatar_url\": \"$CALCROM_DISCORD_WEBHOOK_AVATAR_URL\", \"content\":\"\`\`\`\\n$build_name progress:\\n$output\\n\`\`\`\"}" -H "Content-Type: application/json" -X POST "$CALCROM_DISCORD_WEBHOOK_URL"
|
35
.github/pull_request_template.md
vendored
35
.github/pull_request_template.md
vendored
|
@ -1,35 +0,0 @@
|
|||
<!--- Provide a general summary of your changes in the Title above -->
|
||||
|
||||
<!--- Before submitting, please make sure your pull request meets the scope guidelines. If unsure, please open a thread in #pr-discussions.-->
|
||||
<!--- Scope Guidelines: https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/scope.md -->
|
||||
<!--- #pr-discussions: https://discord.com/channels/419213663107416084/1102784418369785948 -->
|
||||
|
||||
## Description
|
||||
<!--- Describe your changes in detail -->
|
||||
|
||||
## Images
|
||||
<!-- Please provide with relevant GIFs or images to make it easier for reviewers to accept your PR quicker.-->
|
||||
<!-- If it doesn't apply, feel free to remove this section. -->
|
||||
|
||||
## Issue(s) that this PR fixes
|
||||
<!-- Format: "Fixes #2345, fixes #4523, fixes #2222." -->
|
||||
<!-- If it doesn't apply, feel free to remove this section. -->
|
||||
|
||||
## **People who collaborated with me in this PR**
|
||||
<!-- Please credit everyone else that contributed to this PR, be it code and/or assets. -->
|
||||
<!-- Use their GitHub tag if they have one (or add "@/" at the start if they don't). Be sure to start the line using @ so the automatic changelog can properly detect the collaborators. -->
|
||||
<!-- Eg.: "@Lunos for sprites, @/Masuda for support" -->
|
||||
<!-- If it doesn't apply, feel free to remove this section. -->
|
||||
|
||||
## Feature(s) this PR does NOT handle:
|
||||
<!-- If your PR contains any unfinished features that are not considered merge-blocking, please list them here for clarity so no one can forget. -->
|
||||
<!-- If it doesn't apply, feel free to remove this section. -->
|
||||
|
||||
## Things to note in the release changelog:
|
||||
<!-- We use an automated system to generate our changelogs, so if there's something of note that our end users should know in regards to this change besides the title of this PR, they should be added here. -->
|
||||
<!-- *MUST* be structured as bullet points. -->
|
||||
<!-- If it doesn't apply, feel free to remove this section. -->
|
||||
|
||||
## **Discord contact info**
|
||||
<!--- Formatted as username (e.g. Lunos) or username#numbers (e.g. Lunos#4026) -->
|
||||
<!--- Contributors must join https://discord.gg/6CzjAG6GZk -->
|
41
.github/workflows/build.yml
vendored
41
.github/workflows/build.yml
vendored
|
@ -1,41 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- upcoming
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: devkitpro/devkitarm
|
||||
env:
|
||||
GAME_VERSION: EMERALD
|
||||
GAME_REVISION: 0
|
||||
GAME_LANGUAGE: ENGLISH
|
||||
COMPARE: 0
|
||||
UNUSED_ERROR: 1
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install binutils
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential libpng-dev libelf-dev
|
||||
# build-essential and git are already installed
|
||||
# gcc-arm-none-eabi is only needed for the modern build
|
||||
# as an alternative to dkP
|
||||
|
||||
- name: ROM
|
||||
env:
|
||||
COMPARE: 0
|
||||
run: make -j${nproc} -O all
|
||||
|
||||
- name: Test
|
||||
env:
|
||||
TEST: 1
|
||||
run: |
|
||||
make -j${nproc} check
|
48
.github/workflows/docs.yml
vendored
48
.github/workflows/docs.yml
vendored
|
@ -1,48 +0,0 @@
|
|||
name: Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pages: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install latest mdbook
|
||||
run: |
|
||||
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')
|
||||
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
|
||||
mkdir mdbook
|
||||
curl -sSL $url | tar -xz --directory=./mdbook
|
||||
echo `pwd`/mdbook >> $GITHUB_PATH
|
||||
- name: Build Book
|
||||
run: |
|
||||
cd docs
|
||||
mdbook build
|
||||
- name: Check if Pages is enabled
|
||||
uses: octokit/request-action@v2.x
|
||||
id: check_pages
|
||||
continue-on-error: true
|
||||
with:
|
||||
route: GET /repos/{repo}/pages
|
||||
repo: ${{ github.repository }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
if: steps.check_pages.outcome == 'success'
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: 'docs/book'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
if: steps.check_pages.outcome == 'success'
|
61
CHANGELOG.md
61
CHANGELOG.md
|
@ -1,61 +0,0 @@
|
|||
# Pokeemerald-Expansion Changelogs
|
||||
|
||||
## 1.10.x
|
||||
- **[Version 1.10.1](docs/changelogs/1.10.x/1.10.1.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.10.0](docs/changelogs/1.10.x/1.10.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.9.x
|
||||
- **[Version 1.9.4](docs/changelogs/1.9.x/1.9.4.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.9.3](docs/changelogs/1.9.x/1.9.3.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.9.2](docs/changelogs/1.9.x/1.9.2.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.9.1](docs/changelogs/1.9.x/1.9.1.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.9.0](docs/changelogs/1.9.x/1.9.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.8.x
|
||||
- **[Version 1.8.6](docs/changelogs/1.8.x/1.8.6.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.8.5](docs/changelogs/1.8.x/1.8.5.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.8.4](docs/changelogs/1.8.x/1.8.4.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.8.3](docs/changelogs/1.8.x/1.8.3.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.8.2](docs/changelogs/1.8.x/1.8.2.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.8.1](docs/changelogs/1.8.x/1.8.1.md) - 🔥 HOTFIX Release**
|
||||
- **[Version 1.8.0](docs/changelogs/1.8.x/1.8.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.7.x
|
||||
- **[Version 1.7.4](docs/changelogs/1.7.x/1.7.4.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.7.3](docs/changelogs/1.7.x/1.7.3.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.7.2](docs/changelogs/1.7.x/1.7.2.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.7.1](docs/changelogs/1.7.x/1.7.1.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.7.0](docs/changelogs/1.7.x/1.7.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.6.x
|
||||
- **[Version 1.6.2](docs/changelogs/1.6.x/1.6.2.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.6.1](docs/changelogs/1.6.x/1.6.1.md) - 🔥 HOTFIX Release**
|
||||
- **[Version 1.6.0](docs/changelogs/1.6.x/1.6.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.5.x
|
||||
- **[Version 1.5.3](docs/changelogs/1.5.x/1.5.3.md) - 🔥 HOTFIX Release**
|
||||
- **[Version 1.5.2](docs/changelogs/1.5.x/1.5.2.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.5.1](docs/changelogs/1.5.x/1.5.1.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.5.0](docs/changelogs/1.5.x/1.5.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.4.x
|
||||
- **[Version 1.4.3](docs/changelogs/1.4.x/1.4.3.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.4.2](docs/changelogs/1.4.x/1.4.2.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.4.1](docs/changelogs/1.4.x/1.4.1.md) - 🔥 HOTFIX Release**
|
||||
- **[Version 1.4.0](docs/changelogs/1.4.x/1.4.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.3.x
|
||||
- **[Version 1.3.0](docs/changelogs/1.3.x/1.3.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.2.x
|
||||
- **[Version 1.2.0](docs/changelogs/1.2.x/1.2.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.1.x
|
||||
- **[Version 1.1.1](docs/changelogs/1.1.x/1.1.1.md) - 🧹 Bugfix Release**
|
||||
- **[Version 1.1.0](docs/changelogs/1.1.x/1.1.0.md) - ✨ Feature Release**
|
||||
|
||||
## 1.0.x
|
||||
- **[Version 1.0.0](docs/changelogs/1.0.x/1.0.0.md) - ✨ Feature Release**
|
||||
|
||||
## Pre-1.0.x:
|
||||
- **[Version 0.9.0](docs/changelogs/0.9.x/0.9.0.md) - 🦕 Retroactive Version**
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "This script is deprecated. Next time, run \"make tools\" instead."
|
||||
for dname in tools/*; do
|
||||
if [ -f ${dname}/Makefile ]; then
|
||||
make -C ${dname} CXX=${1:-g++} --no-print-directory
|
||||
fi
|
||||
done
|
216
external/poryscript/CHANGELOG.md
vendored
Normal file
216
external/poryscript/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
Nothing, yet.
|
||||
|
||||
## [3.5.1] - 2024-11-24
|
||||
### Fixed
|
||||
- Fix bug where `\N` didn't respect `numLines` when using `format()`.
|
||||
|
||||
## [3.5.0] - 2024-11-10
|
||||
### Added
|
||||
- Movement can now be inlined within commands using a special `moves()` operator, similar to text. For example:
|
||||
```
|
||||
applymovement(OBJ_EVENT_ID_PLAYER, moves(
|
||||
walk_left * 4
|
||||
face_down
|
||||
))
|
||||
```
|
||||
- Print a warning message when `numLines` is missing from a font's config. Defaults to `numLines=2` in that case, rather than `0`.
|
||||
- Added `msgbox` to the default `command_config.json`, since `msgbox(.., MSGBOX_YESNO)` would be a very common use case.
|
||||
|
||||
### Changed
|
||||
- Multi-line string literals will now remove newline characters, and separate each line by a space character instead.
|
||||
- This should rarely, if ever, be used. But the previous behavior resulted in invalid compiled scripts.
|
||||
|
||||
## [3.4.0] - 2024-08-15
|
||||
- Add support for AutoVar commands.
|
||||
- AutoVar commands can be used in place of the `var` operator to streamline comparisons.
|
||||
- AutoVar commands are defined in a new config file `command_config.json`.
|
||||
- Fix missing semicon character in FireRed/LeafGreen font config
|
||||
|
||||
## [3.3.0] - 2024-01-15
|
||||
- Add ability to configure number of lines used by `format()`. For example, this is useful if the text is intended to render in, a 3-line textbox (instead of the usual 2).
|
||||
- Additionally, `format()` now accepts named parameters, and `numLines` has been included in `font_config.json`.
|
||||
|
||||
## [3.2.0] - 2023-12-02
|
||||
### Added
|
||||
- Add `-lm` option for [C Preprocessor line markers](https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_9.html) to improve error messages.
|
||||
- `-lm` is enabled by default. You can specify `-lm=false` to disable line markers in the compiled output.
|
||||
|
||||
## [3.1.0] - 2023-11-11
|
||||
### Added
|
||||
- Add support for configuration of the textbox's cursor width to improve `format()`'s ability to fit text on a line.
|
||||
- This is achieved with a new `cursorOverlapWidth` field in `font_config.json`
|
||||
- Note, this change also changed the `maxLineLength` of the `1_latin_frlg` font, so existing uses of `format()` could be affected--especially when used in combination with explicit line breaks inside the `format()` text content.
|
||||
- Add automatic line break (`\N`) support to `format()`
|
||||
|
||||
## [3.0.3] - 2023-09-04
|
||||
### Fixed
|
||||
- Fix bug where specifying a non-default font id with `format()` would apply the wrong maximum line width configuration.
|
||||
|
||||
## [3.0.2] - 2023-05-20
|
||||
### Fixed
|
||||
- Fix bug where a `switch` statement with all empty `case` bodies would produce invalid output.
|
||||
|
||||
## [3.0.1] - 2023-01-08
|
||||
### Fixed
|
||||
- Fix bug where `end` and `return` commands could cause labels to not render.
|
||||
|
||||
## [3.0.0] - 2022-11-19
|
||||
### Changed
|
||||
- Font configuration file is now called `font_config.json`, and each font in that file contains a `maxLineLength` used by `format()`. The command-line option `-fw` has been renamed to `-fc` to reflect the new name of the font configuration file.
|
||||
|
||||
## [2.14.0] - 2022-06-27
|
||||
### Added
|
||||
- Add the ability to define sub-labels inside `script` statements. This is useful in some cases where it's more ergonomic to directly jump to a desired location inside a script, similar to C's goto labels.
|
||||
|
||||
## [2.13.0] - 2022-06-16
|
||||
### Added
|
||||
- Add `mart` statement, which is a convenient way to define a list of items used with the decomp's `pokemart` script command. Prior to this addition, the mart data had to be encoded using Poryscript's `raw` statement.
|
||||
|
||||
## [2.12.0] - 2021-12-27
|
||||
### Added
|
||||
- Add `value()` operator, which can be used on the right-hand side of a `var()` comparison. It will force a `compare_var_to_value` command to be output. This makes it possible to compare values that occupy the same range as vars (`0x4000 <= x <= 0x40FF` and `0x8000 <= x <= 0x8015`).
|
||||
- Add ability to author inifinite loops using the `while` statement without any boolean expression.
|
||||
|
||||
## [2.11.0] - 2021-10-23
|
||||
### Added
|
||||
- Add -l command-line option to define default line length for formatted text.
|
||||
- Add -f command-line option to define default font id from `font_widths.json` for formatted text.
|
||||
|
||||
## [2.10.0] - 2021-04-03
|
||||
### Added
|
||||
- Add ability to specify custom directives for text. (e.g. `ascii"My ASCII text"` will result in `.ascii "My ASCII text\0"`)
|
||||
|
||||
## [2.9.0] - 2020-09-07
|
||||
### Added
|
||||
- Add optional maximum line length parameter to `format()` operator.
|
||||
|
||||
## [2.8.1] - 2020-05-06
|
||||
### Fixed
|
||||
- Fix bug where `switch` statement `default` case didn't work properly when combined with other cases.
|
||||
|
||||
## [2.8.0] - 2020-03-25
|
||||
### Added
|
||||
- Add ability to use the NOT (`!`) operator in front of nested boolean expressions. Example: `if (flag(A) && !(flag(B) || flag(C)))`
|
||||
|
||||
## [2.7.2] - 2019-11-16
|
||||
### Fixed
|
||||
- Fix bug where implicit text labels weren't properly inserted into command arguments.
|
||||
|
||||
## [2.7.1] - 2019-11-13
|
||||
### Fixed
|
||||
- Fix bug where control codes with spaces in them (e.g. `{COLOR BLUE}`) were not handled properly in `format()`.
|
||||
|
||||
## [2.7.0] - 2019-11-05
|
||||
### Added
|
||||
- Add support for compile-time switches using the `poryswitch` statement. This helps with language differences or game-version differences, for example.
|
||||
- Add support for user-defined constants with `const` keyword. This helps with things like defining event object ids to refer to throughout the script.
|
||||
|
||||
## [2.6.0] - 2019-10-26
|
||||
### Added
|
||||
- Add support for scope modifiers `global` and `local` for `script`, `text`, `movement`, and `mapscripts` statements. This will force labels for be generated with `::` (global) or `:` (local) in the compiled output script.
|
||||
|
||||
## [2.5.0] - 2019-10-16
|
||||
### Added
|
||||
- Comments can now be used with `//`, in addition to the existing '#' style. This is to support users who want to process Poryscript with the C preprocessor.
|
||||
- Add `movement` statement, which is used to define movement data. Use `*` as a shortcut for repeating a movement command many times. `step_end` terminator is automatically added to the end of the data.
|
||||
- Add `mapscripts` statement, which is used to define map scripts. Scripts can be inlined, or simply specified with a label.
|
||||
|
||||
### Fixed
|
||||
- Fix harmless bug where `format()` could result in empty `.string ""` lines in the compiled out.
|
||||
- Fix bug where `end` command was incorrectly being replaced with a `return`.
|
||||
- Fix bug where negative numbers were not parsed correctly.
|
||||
|
||||
## [2.4.0] - 2019-10-13
|
||||
### Added
|
||||
- Add support for text auto-formatting with the `format()` operator. Font widths are loaded from a config JSON file. Specify config file with `-fw <config filepath>`. If `-fw` is omitted, Poryscript will try to load `font_widths.json` by default.
|
||||
|
||||
### Changed
|
||||
- Text is now automatically terminated with a `$` character, so the user doesn't have to manually type it for all pieces of text. Of course, this does not apply to text within `raw` statements.
|
||||
|
||||
## [2.3.0] - 2019-10-12
|
||||
## Added
|
||||
- Add `defeated()` operator, which is used to check if a trainer has been defeated. Without this new `defeated()` operator, it was impossible to write scripts that checked trainer flags without using `raw`.
|
||||
- Add `text` statements.
|
||||
|
||||
## [2.2.0] - 2019-10-07
|
||||
### Changed
|
||||
- Identical implicit texts are now combined into a single text output.
|
||||
|
||||
### Fixed
|
||||
- Fix some potential infinite loops when parsing certain invalid scripts.
|
||||
|
||||
## [2.1.1] - 2019-09-14
|
||||
### Fixed
|
||||
- Fix bug where hexadecimal numbers were not tokenized correctly, resulting in a space after the `0x` prefix.
|
||||
|
||||
## [2.1.0] - 2019-09-11
|
||||
### Added
|
||||
- Add implicit truthiness checks for `var()` and `flag()` operators.
|
||||
- Add NOT (`!`) prefix operator for `var()` and `flag()` operators.
|
||||
|
||||
### Changed
|
||||
- Errors are now prefixed with `PORYSCRIPT`, and they are written to `stderr`, instead of `stdout`.
|
||||
- The program will no longer panic when handled errors occur.
|
||||
|
||||
### Fixed
|
||||
- Fix parser errors that were not showing the line number of the error.
|
||||
|
||||
## [2.0.0] - 2019-09-02
|
||||
### Added
|
||||
- Add single-line comments with the `#` character.
|
||||
- Add `go.mod` file so the project can be built outside of the Go workspace.
|
||||
- Add `while` loops.
|
||||
- Add `do...while` loops.
|
||||
- Add `break` and `continue` statements.
|
||||
- Add compound boolean expressions.
|
||||
- Add output optimization which significantly simplifies and shrinks the resulting compiled scripts. Turn off optimization by specifying `-optimize=false`.
|
||||
- Add `switch` statements.
|
||||
|
||||
### Changed
|
||||
- `raw` no longer takes a label name.
|
||||
- Removed `raw_global`, since there is no longer a concept of being global or local for `raw`.
|
||||
|
||||
### Fixed
|
||||
- Inline texts are now generated with labels that are prefixed to their parent script's name. Otherwise, they would easily clash with external scripts because they were all simply named `Text_<num>`.
|
||||
|
||||
## [1.0.0] - 2019-08-27
|
||||
Initial Release
|
||||
|
||||
[Unreleased]: https://github.com/huderlem/poryscript/compare/3.5.1...HEAD
|
||||
[3.5.0]: https://github.com/huderlem/poryscript/compare/3.5.0...3.5.1
|
||||
[3.5.0]: https://github.com/huderlem/poryscript/compare/3.4.0...3.5.0
|
||||
[3.4.0]: https://github.com/huderlem/poryscript/compare/3.3.0...3.4.0
|
||||
[3.3.0]: https://github.com/huderlem/poryscript/compare/3.2.0...3.3.0
|
||||
[3.2.0]: https://github.com/huderlem/poryscript/compare/3.1.0...3.2.0
|
||||
[3.1.0]: https://github.com/huderlem/poryscript/compare/3.0.3...3.1.0
|
||||
[3.0.3]: https://github.com/huderlem/poryscript/compare/3.0.2...3.0.3
|
||||
[3.0.2]: https://github.com/huderlem/poryscript/compare/3.0.1...3.0.2
|
||||
[3.0.1]: https://github.com/huderlem/poryscript/compare/3.0.0...3.0.1
|
||||
[3.0.0]: https://github.com/huderlem/poryscript/compare/2.14.0...3.0.0
|
||||
[2.14.0]: https://github.com/huderlem/poryscript/compare/2.13.0...2.14.0
|
||||
[2.13.0]: https://github.com/huderlem/poryscript/compare/2.12.0...2.13.0
|
||||
[2.12.0]: https://github.com/huderlem/poryscript/compare/2.11.0...2.12.0
|
||||
[2.11.0]: https://github.com/huderlem/poryscript/compare/2.10.0...2.11.0
|
||||
[2.10.0]: https://github.com/huderlem/poryscript/compare/2.9.0...2.10.0
|
||||
[2.9.0]: https://github.com/huderlem/poryscript/compare/2.8.1...2.9.0
|
||||
[2.8.1]: https://github.com/huderlem/poryscript/compare/2.8.0...2.8.1
|
||||
[2.8.0]: https://github.com/huderlem/poryscript/compare/2.7.2...2.8.0
|
||||
[2.7.2]: https://github.com/huderlem/poryscript/compare/2.7.1...2.7.2
|
||||
[2.7.1]: https://github.com/huderlem/poryscript/compare/2.7.0...2.7.1
|
||||
[2.7.0]: https://github.com/huderlem/poryscript/compare/2.6.0...2.7.0
|
||||
[2.6.0]: https://github.com/huderlem/poryscript/compare/2.5.0...2.6.0
|
||||
[2.5.0]: https://github.com/huderlem/poryscript/compare/2.4.0...2.5.0
|
||||
[2.4.0]: https://github.com/huderlem/poryscript/compare/2.3.0...2.4.0
|
||||
[2.3.0]: https://github.com/huderlem/poryscript/compare/2.2.0...2.3.0
|
||||
[2.2.0]: https://github.com/huderlem/poryscript/compare/2.1.1...2.2.0
|
||||
[2.1.1]: https://github.com/huderlem/poryscript/compare/2.1.0...2.1.1
|
||||
[2.1.0]: https://github.com/huderlem/poryscript/compare/2.0.0...2.1.0
|
||||
[2.0.0]: https://github.com/huderlem/poryscript/compare/1.0.0...2.0.0
|
||||
[1.0.0]: https://github.com/huderlem/poryscript/tree/1.0.0
|
922
external/poryscript/README.md
vendored
Normal file
922
external/poryscript/README.md
vendored
Normal file
|
@ -0,0 +1,922 @@
|
|||
# Poryscript
|
||||
|
||||
[![Actions Status](https://github.com/huderlem/poryscript/workflows/Go/badge.svg)](https://github.com/huderlem/poryscript/actions) [![codecov](https://codecov.io/gh/huderlem/poryscript/branch/master/graph/badge.svg)](https://codecov.io/gh/huderlem/poryscript)
|
||||
|
||||
|
||||
Use the online [Poryscript Playground](http://www.huderlem.com/poryscript-playground/) to test it out.
|
||||
|
||||
Poryscript is a higher-level scripting language that compiles into the scripting language used in [pokeemerald](https://github.com/pret/pokeemerald), [pokefirered](https://github.com/pret/pokefirered), and [pokeruby](https://github.com/pret/pokeruby). It makes scripting faster and easier. Some advantages of using Poryscript are:
|
||||
1. Branching control flow with `if`, `elif`, `else`, `while`, `do...while`, and `switch` statements.
|
||||
2. Inline text
|
||||
3. Auto-formatting text to fit within the in-game text box
|
||||
4. Better map script organization
|
||||
|
||||
View the [Changelog](https://github.com/huderlem/poryscript/blob/master/CHANGELOG.md) to see what's new, and download the latest version from the [Releases](https://github.com/huderlem/poryscript/releases).
|
||||
|
||||
**Table of Contents**
|
||||
- [Usage](#usage)
|
||||
* [Convert Existing Scripts](#convert-existing-scripts)
|
||||
- [Poryscript Syntax (How to Write Scripts)](#poryscript-syntax-how-to-write-scripts)
|
||||
* [`script` Statement](#script-statement)
|
||||
+ [Boolean Expressions](#boolean-expressions)
|
||||
+ [`while` and `do...while` Loops](#while-and-dowhile-loops)
|
||||
+ [Conditional Operators](#conditional-operators)
|
||||
+ [Regular Commands](#regular-commands)
|
||||
+ [Early-Exiting a Script](#early-exiting-a-script)
|
||||
+ [`switch` Statement](#switch-statement)
|
||||
+ [Labels](#labels)
|
||||
* [`text` Statement](#text-statement)
|
||||
+ [Automatic Text Formatting](#automatic-text-formatting)
|
||||
+ [Custom Text Encoding](#custom-text-encoding)
|
||||
* [`movement` Statement](#movement-statement)
|
||||
* [`mart` Statement](#mart-statement)
|
||||
* [`mapscripts` Statement](#mapscripts-statement)
|
||||
* [`raw` Statement](#raw-statement)
|
||||
* [Comments](#comments)
|
||||
* [Constants](#constants)
|
||||
* [Scope Modifiers](#scope-modifiers)
|
||||
* [AutoVar Commands](#autovar-commands)
|
||||
* [Compile-Time Switches](#compile-time-switches)
|
||||
* [Optimization](#optimization)
|
||||
* [Line Markers](#line-markers)
|
||||
- [Local Development](#local-development)
|
||||
* [Building from Source](#building-from-source)
|
||||
* [Running the tests](#running-the-tests)
|
||||
- [Versioning](#versioning)
|
||||
- [License](#license)
|
||||
- [Acknowledgments](#acknowledgments)
|
||||
|
||||
|
||||
# Usage
|
||||
Poryscript is a command-line program. It reads an input script and outputs the resulting compiled bytecode script. You can either feed it the input script from a file or from `stdin`. Similarly, Poryscript can output a file or to `stdout`.
|
||||
|
||||
```
|
||||
> ./poryscript -h
|
||||
Usage of poryscript:
|
||||
-cc string
|
||||
command config JSON file (default "command_config.json")
|
||||
-f string
|
||||
set default font id (leave empty to use default defined in font config file)
|
||||
-fc string
|
||||
font config JSON file (default "font_config.json")
|
||||
-h show poryscript help information
|
||||
-i string
|
||||
input poryscript file (leave empty to read from standard input)
|
||||
-l int
|
||||
set default line length in pixels for formatted text (uses font config file for default)
|
||||
-lm
|
||||
include line markers in output (enables more helpful error messages when compiling the ROM). (To disable, use '-lm=false') (default true)
|
||||
-o string
|
||||
output script file (leave empty to write to standard output)
|
||||
-optimize
|
||||
optimize compiled script size (To disable, use '-optimize=false') (default true)
|
||||
-s value
|
||||
set a compile-time switch. Multiple -s options can be set. Example: -s VERSION=RUBY -s LANGUAGE=GERMAN
|
||||
-v show version of poryscript
|
||||
```
|
||||
|
||||
Convert a `.pory` script to a compiled `.inc` script, which can be directly included in a decompilation project:
|
||||
```
|
||||
./poryscript -i data/scripts/myscript.pory -o data/scripts/myscript.inc
|
||||
```
|
||||
|
||||
To automatically convert your Poryscript scripts when compiling a decomp project, perform these two steps:
|
||||
1. Create a new `tools/poryscript/` directory, and add the `poryscript` command-line executable tool to it. Also copy `command_config.json` and `font_config.json` to the same location.
|
||||
```
|
||||
# For example, on Windows, place the files here.
|
||||
pokeemerald/tools/poryscript/poryscript.exe
|
||||
pokeemerald/tools/poryscript/command_config.json
|
||||
pokeemerald/tools/poryscript/font_config.json
|
||||
```
|
||||
It's also a good idea to add `tools/poryscript` to your `.gitignore` before your next commit.
|
||||
|
||||
2. Update the Makefile with these changes (Note, don't add the `+` symbol at the start of the lines. That's just to show the line is being added.):
|
||||
```diff
|
||||
FIX := $(TOOLS_DIR)/gbafix/gbafix$(EXE)
|
||||
MAPJSON := $(TOOLS_DIR)/mapjson/mapjson$(EXE)
|
||||
JSONPROC := $(TOOLS_DIR)/jsonproc/jsonproc$(EXE)
|
||||
+ SCRIPT := $(TOOLS_DIR)/poryscript/poryscript$(EXE)
|
||||
```
|
||||
```diff
|
||||
include audio_rules.mk
|
||||
|
||||
+AUTO_GEN_TARGETS += $(patsubst %.pory,%.inc,$(shell find data/ -type f -name '*.pory'))
|
||||
|
||||
generated: $(AUTO_GEN_TARGETS)
|
||||
```
|
||||
```diff
|
||||
%.s: ;
|
||||
%.png: ;
|
||||
%.pal: ;
|
||||
%.aif: ;
|
||||
+ %.pory: ;
|
||||
```
|
||||
```diff
|
||||
%.rl: % ; $(GFX) $< $@
|
||||
+ data/%.inc: data/%.pory; $(SCRIPT) -i $< -o $@ -fc tools/poryscript/font_config.json -cc tools/poryscript/command_config.json
|
||||
```
|
||||
|
||||
## Convert Existing Scripts
|
||||
If you're working on a large project, you may want to convert all of the existing `scripts.inc` files to their `scripts.pory` equivalents. Since there are a large number of script files in the Gen 3 projects, you can save yourself a lot of time by following these instructions. **Again, this is completely optional, and you would only want to perform this bulk conversion if you're emabarking on large project where it would be useful to have all the existing scripts setup as Poryscript files.**
|
||||
|
||||
<details>
|
||||
<summary>Click Here to View Instructions</summary>
|
||||
|
||||
Convert all of your projects old map `scripts.inc` files into new `scripts.pory` files while maintaining the old scripts:
|
||||
|
||||
1. Create a file in your `pokeemerald/` directory named `convert_inc.sh` with the following content:
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
for directory in data/maps/* ; do
|
||||
pory_exists=$(find $directory -name $"scripts.pory" | wc -l)
|
||||
if [[ $pory_exists -eq 0 ]];
|
||||
then
|
||||
inc_exists=$(find $directory -name $"scripts.inc" | wc -l)
|
||||
if [[ $inc_exists -ne 0 ]];
|
||||
then
|
||||
echo "Converting: $directory/scripts.inc"
|
||||
touch "$directory/scripts.pory"
|
||||
echo 'raw `' >> "$directory/scripts.pory"
|
||||
cat "$directory/scripts.inc" >> "$directory/scripts.pory"
|
||||
echo '`' >> "$directory/scripts.pory"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
2. Run `chmod 777 convert_inc.sh` to ensure the script executable.
|
||||
|
||||
Finally you can execute it in your `pokeemerald/` directory by running `./convert_inc.sh` or `bash convert_inc.sh` in the console. This script will iterate through all your `data/map/` directories and convert the `scripts.inc` files into `scripts.pory` files by adding a `raw` tag around the old scripts. `convert_inc.sh` will skip over any directories that already have `scripts.pory` files in them, so that it will not overwrite any maps that you have already switched over to Poryscript.
|
||||
</details>
|
||||
|
||||
# Poryscript Syntax (How to Write Scripts)
|
||||
|
||||
A single `.pory` file is composed of many top-level statements. The valid top-level statements are `script`, `text`, `movement`, `mart`, `mapscripts`, and `raw`.
|
||||
```
|
||||
mapscripts MyMap_MapScripts {
|
||||
...
|
||||
}
|
||||
|
||||
script MyScript {
|
||||
...
|
||||
}
|
||||
|
||||
text MyText {
|
||||
"Hi, I'm some text.\n"
|
||||
"I'm global and can be accessed in C code."
|
||||
}
|
||||
|
||||
movement MyMovement {
|
||||
walk_left
|
||||
walk_right * 3
|
||||
}
|
||||
|
||||
mart MyMart {
|
||||
ITEM_POTION
|
||||
ITEM_POKEBALL
|
||||
}
|
||||
|
||||
raw `
|
||||
MyLocalText:
|
||||
.string "I'm directly included.$"
|
||||
`
|
||||
```
|
||||
|
||||
## `script` Statement
|
||||
The `script` statement creates a global script containing script commands and control flow logic. Here is an example:
|
||||
```
|
||||
script MyScript {
|
||||
# Show a different message, depending on the state of different flags.
|
||||
lock
|
||||
faceplayer
|
||||
if (flag(FLAG_RECEIVED_TOP_PRIZE)) {
|
||||
msgbox("You received the best prize!")
|
||||
} elif (flag(FLAG_RECEIVED_WORST_PRIZE)) {
|
||||
msgbox("Ouch, you received the worst prize.")
|
||||
} else {
|
||||
msgbox("Hmm, you didn't receive anything.")
|
||||
}
|
||||
release
|
||||
end
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, using `if` statements greatly simplifies writing scripts because it does not require the author to manually define new sub-labels with `goto` statements everywhere.
|
||||
|
||||
`if` statements can be nested inside each other, as you would expect.
|
||||
```
|
||||
if (flag(FLAG_TEMP) == true) {
|
||||
if (var(VAR_BADGES) < 8) {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note the special keyword `elif`. This is just the way Poryscript specifies an "else if". Many `elif` statements can be chained together.
|
||||
|
||||
### Boolean Expressions
|
||||
Compound boolean expressions are also supported. This means you can use the AND (`&&`) and OR (`||`) logical operators to combine expressions. For example:
|
||||
```
|
||||
# Basic AND of two conditions.
|
||||
if (!defeated(TRAINER_MISTY) && var(VAR_TIME) != DAY) {
|
||||
msgbox("The Cerulean Gym's doors don't\n"
|
||||
"open until morning.")
|
||||
}
|
||||
...
|
||||
# Group nested conditions together with another set of parentheses.
|
||||
if (flag(FLAG_IS_CHAMPION) && !(flag(FLAG_SYS_TOWER_GOLD) || flag(FLAG_SYS_DOME_GOLD))) {
|
||||
msgbox("You should try to beat the\n"
|
||||
"Battle Tower or Battle Dome!")
|
||||
}
|
||||
```
|
||||
|
||||
### `while` and `do...while` Loops
|
||||
`while` statements are used to do loops. They can be nested inside each or inside `if` statements, as one would expect.
|
||||
```
|
||||
# Force player to answer "Yes" to NPC question.
|
||||
msgbox("Do you agree to the quest?", MSGBOX_YESNO)
|
||||
while (var(VAR_RESULT) != 1) {
|
||||
msgbox("...How about now?", MSGBOX_YESNO)
|
||||
}
|
||||
setvar(VAR_QUEST_ACCEPTED, 1)
|
||||
```
|
||||
|
||||
The `while` statement can also be written as an infinite loop by omitting the boolean expression. This would be equivalent to `while(true)` in typical programming languages. (Of course, you'll want to `break` out of the infinite loop, or hard-stop the script.)
|
||||
```
|
||||
while {
|
||||
msgbox("Want to see this message again?", MSGBOX_YESNO)
|
||||
if (var(VAR_RESULT) != 1) {
|
||||
break
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`do...while` statements are very similar to `while` statements. The only difference is that they always execute their body once before checking the condition.
|
||||
```
|
||||
# Force player to answer "Yes" to NPC question.
|
||||
do {
|
||||
msgbox("Can you help me solve the puzzle?", MSGBOX_YESNO)
|
||||
} while (var(VAR_RESULT) == 0)
|
||||
```
|
||||
|
||||
`break` can be used to break out of a loop, like many programming languages. Similary, `continue` returns to the start of the loop.
|
||||
|
||||
### Conditional Operators
|
||||
The condition operators have strict rules about what conditions they accept. The operand on the left side of the condition must be a `flag()`, `var()`, `defeated()`, or [AutoVar](#autovar-commands) check. They each have a different set of valid comparison operators, described below.
|
||||
|
||||
| Type | Valid Operators |
|
||||
| ---- | --------------- |
|
||||
| `flag` | `==` |
|
||||
| `var` or [AutoVar](#autovar-commands) | `==`, `!=`, `>`, `>=`, `<`, `<=` |
|
||||
| `defeated` | `==` |
|
||||
|
||||
All operators support implicit truthiness, which means you don't have to specify any of the above operators in a condition. Below are some examples of equivalent conditions:
|
||||
```
|
||||
# Check if the flag is set.
|
||||
if (flag(FLAG_1))
|
||||
if (flag(FLAG_1) == true)
|
||||
|
||||
# Check if the flag is cleared.
|
||||
if (!flag(FLAG_1))
|
||||
if (flag(FLAG_1) == false)
|
||||
|
||||
# Check if the var is not equal to 0.
|
||||
if (var(VAR_1))
|
||||
if (var(VAR_1) != 0)
|
||||
|
||||
#Check if the var is equal to 0.
|
||||
if (!var(VAR_1))
|
||||
if (var(VAR_1) == 0)
|
||||
|
||||
# Check if the trainer has been defeated.
|
||||
if (defeated(TRAINER_GARY))
|
||||
if (defeated(TRAINER_GARY) == true)
|
||||
|
||||
# Check if the trainer hasn't been defeated.
|
||||
if (!defeated(TRAINER_GARY))
|
||||
if (defeated(TRAINER_GARY) == false)
|
||||
```
|
||||
|
||||
When not using implicit truthiness, like in the above examples, they each have different valid comparison values on the right-hand side of the condition.
|
||||
|
||||
| Type | Valid Comparison Values |
|
||||
| ---- | --------------- |
|
||||
| `flag` | `TRUE`, `true`, `FALSE`, `false` |
|
||||
| `var` | any value (e.g. `5`, `VAR_TEMP_1`, `VAR_FOO + BASE_OFFSET`) |
|
||||
| `defeated` | `TRUE`, `true`, `FALSE`, `false` |
|
||||
|
||||
One quirk of the Gen 3 decomp scripting engine is that using the `compare` scripting command with a value in the range `0x4000 <= x <= 0x40FF` or `0x8000 <= x <= 0x8015` will result in comparing against a `var`, rather than the raw value. To force the comparison against a raw value, like `0x4000`, use the `value()` operator. For example:
|
||||
|
||||
```
|
||||
if (var(VAR_DAMAGE_DEALT) >= value(0x4000))
|
||||
```
|
||||
|
||||
The resulting script use the `compare_var_to_value` command, rather than the usual `compare` command.
|
||||
|
||||
### Regular Commands
|
||||
Regular non-branching commands that take arguments, such as `msgbox`, must wrap their arguments in parentheses. For example:
|
||||
```
|
||||
lock
|
||||
faceplayer
|
||||
addvar(VAR_TALKED_COUNT, 1)
|
||||
msgbox("Hello.")
|
||||
release
|
||||
end
|
||||
```
|
||||
|
||||
### Early-Exiting a Script
|
||||
Use `end` or `return` to early-exit out of a script.
|
||||
```
|
||||
script MyScript {
|
||||
if (flag(FLAG_WON) == true) {
|
||||
end
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### `switch` Statement
|
||||
A `switch` statement is an easy way to separate different logic for a set of concrete values. Poryscript `switch` statements behave similarly to other languages. However, the cases `break` implicitly. It is not possible to "fall through" to the next case by omitting a `break` at the end of a case, like in C. You *can* use `break` to break out of a case, though--it's just not required. Multiple cases can be designated by listing them immediately after another without a body. Finally, an optional `default` case will take over if none of the provided `case` values are met. A `switch` statement's comparison value *must always be a `var()` operator*. Of course, `switch` statements can appear anywhere in the script's logic, such as inside `while` loops, or even other `switch` statements.
|
||||
|
||||
```
|
||||
switch (var(VAR_NUM_THINGS)) {
|
||||
case 0:
|
||||
msgbox("You have 0 things.")
|
||||
case 1:
|
||||
case 2:
|
||||
msgbox("You have 1 or 2 things.")
|
||||
default:
|
||||
msgbox("You have at least 3 things.")
|
||||
}
|
||||
```
|
||||
|
||||
### Labels
|
||||
Labels can be defined inside a `script`, and they are very similar to C's `goto` labels. A label isn't usually desired or needed when writing Poryscript scripts, but it can be useful and in certain situations where you might want to jump to a common part of your script from several different places. To write a label, simply add a colon (`:`) after a name anywhere inside a `script`. Labels are rendered as regular assembly labels, and they can be marked as local or global. By default, labels have local scope, but they can be changed to global scope using the same syntax as other statements (e.g. `MyLabel(global):`).
|
||||
|
||||
Label Example:
|
||||
```
|
||||
// Note, this is a bad example of where a
|
||||
// label would be useful.
|
||||
script MyScript {
|
||||
lockall
|
||||
if (flag(FLAG_TEST)) {
|
||||
goto(MyScript_End)
|
||||
} elif (flag(FLAG_OTHER_TEST)) {
|
||||
addvar(VAR_SCORE, 1)
|
||||
goto(MyScript_End)
|
||||
}
|
||||
|
||||
MyScript_End:
|
||||
releaseall
|
||||
}
|
||||
```
|
||||
|
||||
## `text` Statement
|
||||
Use `text` to include text that's intended to be shared between multiple scripts or in C code. The `text` statement is just a convenient way to write chunks of text, and it exports the text globally, so it is accessible in C code. Currently, there isn't much of a reason to use `text`, but it will be more useful in future updates of Poryscript.
|
||||
```
|
||||
script MyScript {
|
||||
msgbox(MyText)
|
||||
}
|
||||
|
||||
text MyText {
|
||||
"Hello, there.\p"
|
||||
"You can refer to me in scripts or C code."
|
||||
}
|
||||
```
|
||||
A small quality-of-life feature is that Poryscript automatically adds the `$` terminator character to text, so the user doesn't need to manually type it all the time.
|
||||
|
||||
### Automatic Text Formatting
|
||||
Text auto-formatting is also supported by Poryscript. The `format()` function can be wrapped around any text, either inline or `text`, and Poryscript will automatically fit the text to the size of the in-game text window by inserting automatic line breaks. A simple example:
|
||||
```
|
||||
msgbox(format("Hello, this is some long text that I want Poryscript to automatically format for me."))
|
||||
```
|
||||
Becomes:
|
||||
```
|
||||
.string "Hello, this is some long text that I\n"
|
||||
.string "want Poryscript to automatically\l"
|
||||
.string "format for me.$"
|
||||
```
|
||||
Like other text, formatted text can span multiple lines if you use a new set of quotes for each line. You can also manually add your own line breaks (`\p`, `\n`, `\l`), and it will still work as expected.
|
||||
```
|
||||
text MyText {
|
||||
format("Hello, are you the real-live legendary {PLAYER} that everyone talks about?\p"
|
||||
"Amazing!\pSo glad to meet you!")
|
||||
}
|
||||
```
|
||||
Becomes:
|
||||
```
|
||||
.string "Hello, are you the real-live legendary\n"
|
||||
.string "{PLAYER} that everyone talks about?\p"
|
||||
.string "Amazing!\p"
|
||||
.string "So glad to meet you!$"
|
||||
```
|
||||
|
||||
Additionally, `format()` supports a special line break `\N`, which will automatically insert the appropriate `\n` or `\l` line break. While this is an uncommon use case, it's useful in situations where a line break is desired for dramatic/stylistic purposes. In the following example, we want explicit line breaks for the `"..."` texts, but we don't know if the first one should use `\n` or `\l`. Using `\N` makes it easy:
|
||||
```
|
||||
text MyText {
|
||||
format("You are my favorite trainer!\N...\N...\N...\NBut I'm better!")
|
||||
}
|
||||
```
|
||||
|
||||
The font id can optionally be specified as the second parameter to `format()`.
|
||||
```
|
||||
text MyText {
|
||||
format("Hello, are you the real-live legendary {PLAYER} that everyone talks about?\pAmazing!\pSo glad to meet you!", "1_latin_rse")
|
||||
}
|
||||
```
|
||||
Becomes:
|
||||
```
|
||||
.string "Hello, are you the real-live legendary\n"
|
||||
.string "{PLAYER} that everyone talks about?\p"
|
||||
.string "Amazing!\p"
|
||||
.string "So glad to meet you!$"
|
||||
```
|
||||
The font configuration JSON file informs Poryscript how many pixels wide each character in the message is, as well as setting a default maximum line length. Fonts have different character widths, and games have different text box sizes. For convenience, Poryscript comes with `font_config.json`, which contains the configuration for pokeemerald's `1_latin` font as `1_latin_rse`, as well as pokefirered's equivalent as `1_latin_frlg`. More fonts can be added to this file by simply creating anothing font id node under the `fonts` key in `font_config.json`.
|
||||
|
||||
`cursorOverlapWidth` can be used to ensure there is always enough room for the cursor icon to be displayed in the text box. (This "cursor icon" is the small icon that's shown when the player needs to press A to advance the text box.)
|
||||
|
||||
`numLines` is the number of lines displayed within a single message box. If editing text for a taller space, this can be adjusted in `font_config.json`.
|
||||
|
||||
The length of a line can optionally be specified as the third parameter to `format()` if a font id was specified as the second parameter.
|
||||
|
||||
```
|
||||
text MyText {
|
||||
format("Hello, are you the real-live legendary {PLAYER} that everyone talks about?\pAmazing!\pSo glad to meet you!", "1_latin_rse", 100)
|
||||
}
|
||||
```
|
||||
Becomes:
|
||||
```
|
||||
.string "Hello, are you the\n"
|
||||
.string "real-live\l"
|
||||
.string "legendary\l"
|
||||
.string "{PLAYER} that\l"
|
||||
.string "everyone talks\l"
|
||||
.string "about?\p"
|
||||
.string "Amazing!\p"
|
||||
.string "So glad to meet\n"
|
||||
.string "you!$"
|
||||
```
|
||||
|
||||
Finally, `format()` takes the following optional named parameters, which override settings from the font config:
|
||||
- `fontId`
|
||||
- `maxLineLength`
|
||||
- `numLines`
|
||||
- `cursorOverlapWidth`
|
||||
```
|
||||
text MyText {
|
||||
format("This is an example of named parameters!", numLines=3, maxLineLength=100)
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Text Encoding
|
||||
When Poryscript compiles text, the resulting text content is rendered using the `.string` assembler directive. The decomp projects' build process then processes those `.string` directives and substituted the string characters with the game-specific text representation. It can be useful to specify different types of strings, though. For example, implementing print-debugging commands might make use of ASCII text. Poryscript allows you to specify which assembler directive to use for text. Simply add the directive as a prefix to the string content like this:
|
||||
```
|
||||
ascii"My ASCII string."
|
||||
custom"My Custom string."
|
||||
|
||||
// compiles to...
|
||||
.ascii "My ASCII string.\0"
|
||||
.custom "My Custom string."
|
||||
```
|
||||
|
||||
Note that Poryscript will automatically add the `\0` suffix character to ASCII strings. It will **not** add suffix to any other directives.
|
||||
|
||||
## `movement` Statement
|
||||
Use `movement` statements to conveniently define movement data that is typically used with the `applymovement` command. `*` can be used as a shortcut to repeat a single command many times. Data defined with `movement` is created with local scope, not global.
|
||||
```
|
||||
script MyScript {
|
||||
lock
|
||||
applymovement(2, MyMovement)
|
||||
waitmovement(0)
|
||||
release
|
||||
}
|
||||
movement MyMovement {
|
||||
walk_left
|
||||
walk_up * 5
|
||||
face_down
|
||||
}
|
||||
```
|
||||
Becomes:
|
||||
```
|
||||
MyScript::
|
||||
lock
|
||||
applymovement 2, MyMovement
|
||||
waitmovement 0
|
||||
release
|
||||
return
|
||||
|
||||
MyMovement:
|
||||
walk_left
|
||||
walk_up
|
||||
walk_up
|
||||
walk_up
|
||||
walk_up
|
||||
walk_up
|
||||
face_down
|
||||
step_end
|
||||
```
|
||||
|
||||
However, movement can also be *inlined* inside commands similar to text, using the `moves()` operator. This is often much more convenient, and it can help simplify your scripts. Anything that can be used in a `movement` statement can also be used inside `moves()`.
|
||||
|
||||
Looking at the previous example, the movement can be inlined like this:
|
||||
```
|
||||
script MyScript {
|
||||
lock
|
||||
applymovement(2, moves(
|
||||
walk_left
|
||||
walk_up * 5
|
||||
face_down
|
||||
))
|
||||
waitmovement(0)
|
||||
release
|
||||
}
|
||||
```
|
||||
Note, whitespace doesn't matter. This can also be written all on a single line:
|
||||
```
|
||||
applymovement(2, moves(walk_left walk_up * 5 face_down))
|
||||
|
||||
// You can even use commas to separate each movement command, since
|
||||
// that may be easier to read.
|
||||
applymovement(2, moves(walk_left, walk_up * 5, face_down))
|
||||
```
|
||||
|
||||
## `mart` Statement
|
||||
Use `mart` statements to define a list of items for use with the `pokemart` command. Data defined with the `mart` statement is created with local scope by default. It is not neccesary to add `ITEM_NONE` to the end of the list, but if Poryscript encounters it, any items after it will be ignored.
|
||||
|
||||
```
|
||||
script ScriptWithPokemart {
|
||||
lock
|
||||
message("Welcome to my store.")
|
||||
waitmessage
|
||||
pokemart(MyMartItems)
|
||||
msgbox("Come again soon.")
|
||||
release
|
||||
}
|
||||
|
||||
mart MyMartItems {
|
||||
ITEM_LAVA_COOKIE
|
||||
ITEM_MOOMOO_MILK
|
||||
ITEM_RARE_CANDY
|
||||
ITEM_LEMONADE
|
||||
ITEM_BERRY_JUICE
|
||||
}
|
||||
```
|
||||
|
||||
Becomes:
|
||||
```
|
||||
ScriptWithPokemart::
|
||||
lock
|
||||
message ScriptWithPokemart_Text_0
|
||||
waitmessage
|
||||
pokemart MyMartItems
|
||||
msgbox ScriptWithPokemart_Text_1
|
||||
release
|
||||
return
|
||||
|
||||
.align 2
|
||||
MyMartItems:
|
||||
.2byte ITEM_LAVA_COOKIE
|
||||
.2byte ITEM_MOOMOO_MILK
|
||||
.2byte ITEM_RARE_CANDY
|
||||
.2byte ITEM_LEMONADE
|
||||
.2byte ITEM_BERRY_JUICE
|
||||
.2byte ITEM_NONE
|
||||
|
||||
ScriptWithPokemart_Text_0:
|
||||
.string "Welcome to my store.$"
|
||||
|
||||
ScriptWithPokemart_Text_1:
|
||||
.string "Come again soon.$"
|
||||
```
|
||||
|
||||
## `mapscripts` Statement
|
||||
Use `mapscripts` to define a set of map script definitions. Scripts can be inlined for convenience, or a label to another script can simply be specified. Some map script types, like `MAP_SCRIPT_ON_FRAME_TABLE`, require a list of comparison variables and scripts to execute when the variable's value is equal to some value. In these cases, you use brackets `[]` to specify that list of scripts. Below is a full example showing map script definitions for a new map called `MyNewCity`:
|
||||
```
|
||||
mapscripts MyNewCity_MapScripts {
|
||||
MAP_SCRIPT_ON_RESUME: MyNewCity_OnResume
|
||||
MAP_SCRIPT_ON_TRANSITION {
|
||||
random(2)
|
||||
switch (var(VAR_RESULT)) {
|
||||
case 0: setweather(WEATHER_ASH)
|
||||
case 1: setweather(WEATHER_RAIN_HEAVY)
|
||||
}
|
||||
}
|
||||
MAP_SCRIPT_ON_FRAME_TABLE [
|
||||
VAR_TEMP_0, 0: MyNewCity_OnFrame_0
|
||||
VAR_TEMP_0, 1 {
|
||||
lock
|
||||
msgbox("This script is inlined.")
|
||||
setvar(VAR_TEMP_0, 2)
|
||||
release
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
script MyNewCity_OnResume {
|
||||
...
|
||||
}
|
||||
|
||||
script MyNewCity_OnFrame_0 {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
For maps with no map scripts, simply make an empty `mapscripts` statement:
|
||||
```
|
||||
mapscripts MyNewCity_MapScripts {}
|
||||
```
|
||||
|
||||
## `raw` Statement
|
||||
Use `raw` to include raw bytecode script. Anything in a `raw` statement will be directly included into the compiled script. This is useful for defining custom data, or data types not supported in regular Poryscript.
|
||||
```
|
||||
raw `
|
||||
TestMap_MapScripts::
|
||||
.byte 0
|
||||
`
|
||||
|
||||
script MyScript {
|
||||
lock
|
||||
faceplayer
|
||||
# Text can span multiple lines. Use a new set of quotes for each line.
|
||||
msgbox("This is shorter text,\n"
|
||||
"but we can still put it\l"
|
||||
"on multiple lines.")
|
||||
applymovement(OBJ_EVENT_ID_PLAYER, MyScript_Movement)
|
||||
waitmovement(0)
|
||||
msgbox(MyScript_LongText)
|
||||
release
|
||||
end
|
||||
}
|
||||
|
||||
raw `
|
||||
MyScript_Movement:
|
||||
walk_left
|
||||
walk_down
|
||||
step_end
|
||||
|
||||
MyScript_LongText:
|
||||
.string "Hi, there.\p"
|
||||
.string "This text is too long\n"
|
||||
.string "to inline above.\p"
|
||||
.string "We'll put it down here\n"
|
||||
.string "instead, so it's out of\l"
|
||||
.string "the way.$"
|
||||
`
|
||||
```
|
||||
|
||||
## Comments
|
||||
Use single-line comments with `#` or `//`. Everything after the `#` or `//` will be ignored. Comments cannot be placed in a `raw` statement. (Users who wish to run the C preprocessor on Poryscript files should use `//` comments to avoid conflict with C preprocessor directives that use the `#` character.)
|
||||
```
|
||||
# This script does some cool things.
|
||||
script MyScript {
|
||||
// This is also a valid comment.
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Constants
|
||||
Use `const` to define constants that can be used in the current script. This is especially useful for giving human-friendly names to event object ids, or temporary flags. Constants must be defined before they are used. Constants can also be composed of previously-defined constants.
|
||||
```
|
||||
const PROF_BIRCH_ID = 3
|
||||
const ASSISTANT_ID = PROF_BIRCH_ID + 1
|
||||
const FLAG_GREETED_BIRCH = FLAG_TEMP_2
|
||||
|
||||
script ProfBirchScript {
|
||||
applymovement(PROF_BIRCH_ID, moves(walk_left * 4, face_down))
|
||||
showobject(ASSISTANT_ID)
|
||||
setflag(FLAG_GREETED_BIRCH)
|
||||
}
|
||||
```
|
||||
|
||||
Note that these constants are **not** a general macro system. They can only be used in certain places in Poryscript syntax. Below is an example of all possible places where constants can be substituted into the script:
|
||||
```
|
||||
const CONSTANT = 1
|
||||
|
||||
mapscripts MyMapScripts {
|
||||
MAP_SCRIPT_ON_FRAME_TABLE [
|
||||
// The operand and comparison values can both use constants in a
|
||||
// table-based map script.
|
||||
CONSTANT, CONSTANT: MyOnFrameScript_0
|
||||
]
|
||||
}
|
||||
|
||||
script MyScript {
|
||||
// Any parameter of any command can use constants.
|
||||
somecommand(CONSTANT)
|
||||
|
||||
// Any comparison operator can use constants, as well as their comparison values.
|
||||
if (flag(CONSTANT)) {}
|
||||
if (var(CONSTANT) == CONSTANT) {}
|
||||
if (defeated(CONSTANT)) {}
|
||||
|
||||
// A switch var value can be a constant, as well as the individual cases.
|
||||
switch (var(CONSTANT)) {
|
||||
case CONSTANT: break
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Scope Modifiers
|
||||
To control whether a script should be global or local, a scope modifier can be specified. This is supported for `script`, `text`, `movement`, and `mapscripts`. In this context, "global" means that the label will be defined with two colons `::`. Local scopes means one colon `:`.
|
||||
```
|
||||
script(global) MyGlobalScript {
|
||||
...
|
||||
}
|
||||
script(local) MyLocalScript {
|
||||
...
|
||||
}
|
||||
```
|
||||
Becomes:
|
||||
```
|
||||
MyGlobalScript::
|
||||
...
|
||||
|
||||
MyLocalScript:
|
||||
...
|
||||
```
|
||||
|
||||
The top-level statements have different default scopes. They are as follows:
|
||||
|
||||
| Type | Default Scope |
|
||||
| ---- | --------------- |
|
||||
| `script` | Global |
|
||||
| `text` | Global |
|
||||
| `movement` | Local |
|
||||
| `mart` | Local |
|
||||
| `mapscripts` | Global |
|
||||
|
||||
## AutoVar Commands
|
||||
Some scripting commands always store their result in the same variable. For example, `checkitem` always stores its result in `VAR_RESULT`. Poryscript can simplify working with these commands with a concept called "AutoVar" commands.
|
||||
|
||||
*Without* using an AutoVar, a script would be written like this:
|
||||
```
|
||||
checkitem(ITEM_ROOT_FOSSIL)
|
||||
if (var(VAR_RESULT) == TRUE) {
|
||||
// player has the Root Fossil
|
||||
}
|
||||
```
|
||||
|
||||
However, AutoVars can be used *inside* the condition, which helps streamline the script:
|
||||
```
|
||||
if (checkitem(ITEM_ROOT_FOSSIL) == TRUE) {
|
||||
// player has the Root Fossil
|
||||
}
|
||||
```
|
||||
|
||||
AutoVars can be used ***anywhere*** a `var()` operator can be used. e.g. `if` conditions, `switch` statements--any boolean expression!
|
||||
|
||||
### Defining AutoVar Commands
|
||||
AutoVar commands are fully configurable with the `command_config.json` file. Use the `-cc` command line parameter to specifying the location of that config.
|
||||
|
||||
There are two types of AutoVar commands:
|
||||
1. Implicit
|
||||
- The stored var is defined in the config file, and is not present in the authored script.
|
||||
- Examples: `checkitem`, `getpartysize`, `random`
|
||||
2. Explicit
|
||||
- The stored var is provided as part of the command, and the config file stores the 0-based index of the command that specifies the stored var.
|
||||
- Examples: `specialvar`, `checkcoins`
|
||||
|
||||
Let's take a look at the example config file:
|
||||
```json
|
||||
// command_config.json
|
||||
{
|
||||
"autovar_commands": {
|
||||
"specialvar": {
|
||||
"var_name_arg_position": 0
|
||||
},
|
||||
"checkitem": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
With the above config, a script could be written like so:
|
||||
```
|
||||
if (checkitem(ITEM_POKEBLOCK_CASE)) {
|
||||
if (specialvar(VAR_RESULT, GetFirstFreePokeblockSlot) != -1 &&
|
||||
specialvar(VAR_RESULT, PlayerHasBerries)
|
||||
) {
|
||||
msgbox("Great! You can use the Berry Blender!)
|
||||
}
|
||||
} else {
|
||||
msgbox("You don't have a Pokeblock case!")
|
||||
}
|
||||
```
|
||||
|
||||
## Compile-Time Switches
|
||||
Use the `poryswitch` statement to change compiler behavior depending on custom switches. This makes it easy to make scripts behave different depending on, say, the `GAME_VERSION` or `LANGUAGE`. Any content that does not match the compile-time switch will not be included in the final output. To define custom switches, use the `-s` option when running `poryscript`. You can specify multiple switches, and each key/value pair must be separated by an equals sign. For example:
|
||||
|
||||
```
|
||||
./poryscript -i script.pory -o script.inc -s GAME_VERSION=RUBY -s LANGUAGE=GERMAN
|
||||
```
|
||||
|
||||
The `poryswitch` statement can be embedded into any script section, including `text`, `movement`, and `mart` statements. The underscore `_` case is used as the fallback, if none of the other cases match. Cases that only contain a single statement or command can be started with a colon `:`. Otherwise, use curly braces to define the case's block.
|
||||
|
||||
Here are some examples of compile-time switches. This assumes that two compile-time switches are defined, `GAME_VERSION` and `LANGUAGE`.
|
||||
|
||||
```
|
||||
script MyScript {
|
||||
lock
|
||||
faceplayer
|
||||
poryswitch(GAME_VERSION) {
|
||||
RUBY {
|
||||
msgbox("Here, take this Ruby Orb.")
|
||||
giveitem(ITEM_RUBY_ORB)
|
||||
}
|
||||
SAPPHIRE {
|
||||
msgbox("Here, take this Sapphire Orb.")
|
||||
giveitem(ITEM_SAPPHIRE_ORB)
|
||||
}
|
||||
_: msgbox(format("This case is used when GAME_VERSION doesn't match either of the above."))
|
||||
}
|
||||
release
|
||||
}
|
||||
|
||||
text MyText {
|
||||
poryswitch(LANGUAGE) {
|
||||
GERMAN: "Hallo. Ich spreche Deutsch."
|
||||
ENGLISH: "Hello. I speak English."
|
||||
}
|
||||
}
|
||||
|
||||
movement MyMovement {
|
||||
face_player
|
||||
walk_down
|
||||
poryswitch(GAME_VERSION) {
|
||||
RUBY: walk_left * 2
|
||||
SAPPHIRE {
|
||||
walk_right * 2
|
||||
walk_left * 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mart MyMart {
|
||||
ITEM_POTION
|
||||
ITEM_POKEBALL
|
||||
poryswitch(GAME_VERSION) {
|
||||
RUBY {
|
||||
ITEM_LAVA_COOKIE
|
||||
ITEM_RED_SCARF
|
||||
}
|
||||
SAPPHIRE {
|
||||
ITEM_FRESH_WATER
|
||||
ITEM_BLUE_SCARF
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note, `poryswitch` can also be embedded inside inlined `mapscripts` scripts.
|
||||
|
||||
## Optimization
|
||||
By default, Poryscript produces optimized output. It attempts to minimize the number of `goto` commands and unnecessary script labels. To disable optimizations, pass the `-optimize=false` option to `poryscript`.
|
||||
|
||||
## Line Markers
|
||||
By default, Poryscript includes [C Preprocessor line markers](https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_9.html) in the compiled output. This improves error messages. To disable line markers, specify `-lm=false` when invoking Poryscript.
|
||||
|
||||
# Local Development
|
||||
|
||||
These instructions will get you setup and working with Poryscript's code. You can either build the Poryscript tool from source, or simply download the latest release from the Releases tab on GitHub.
|
||||
|
||||
## Building from Source
|
||||
|
||||
First, install [Go](http://golang.org). Poryscript has no additional dependencies. It uses Go modules, so you shouldn't need to be located in a Go workspace.
|
||||
|
||||
Navigate to the Poryscript working directory, and build it:
|
||||
```
|
||||
cd your/path/to/poryscript
|
||||
go build
|
||||
```
|
||||
|
||||
This will create a `poryscript` executable binary in the same directory. Then you can simply install it into your project by running `./install.sh ../yourprojectname` instead of manually copying the files over, similarly to how agbcc is installed into projects.
|
||||
|
||||
## Running the tests
|
||||
|
||||
Poryscript has automated tests for its `emitter`, `parser`, and `lexer` packages. To run all of the tests from the base directory:
|
||||
```
|
||||
> go test ./...
|
||||
? github.com/huderlem/poryscript [no test files]
|
||||
? github.com/huderlem/poryscript/ast [no test files]
|
||||
ok github.com/huderlem/poryscript/emitter 0.523s
|
||||
ok github.com/huderlem/poryscript/lexer 0.273s
|
||||
ok github.com/huderlem/poryscript/parser 0.779s
|
||||
? github.com/huderlem/poryscript/token [no test files]
|
||||
```
|
||||
|
||||
|
||||
# Versioning
|
||||
|
||||
Poryscript uses [Semantic Versioning](http://semver.org/). For the available versions, see the [tags on this repository](https://github.com/huderlem/poryscript/tags).
|
||||
|
||||
# License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
|
||||
|
||||
# Acknowledgments
|
||||
|
||||
* Thorsten Ball's *Writing An Interpreter In Go* helped bootstrap the lexer, AST, and parser for this project. A chunk of that code was derived and/or copied from that book, as I had never written something of this nature before.
|
97
external/poryscript/command_config.json
vendored
Normal file
97
external/poryscript/command_config.json
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"autovar_commands": {
|
||||
"specialvar": {
|
||||
"var_name_arg_position": 0
|
||||
},
|
||||
"getpartysize": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"additem": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"removeitem": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkitemspace": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkitem": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkitemtype": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"addpcitem": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkpcitem": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"adddecoration": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"removedecoration": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkdecor": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkdecorspace": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"yesnobox": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"multichoice": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"multichoicedefault": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"multichoicegrid": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"givemon": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"giveegg": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkpartymove": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"choosecontestmon": {
|
||||
"var_name": "VAR_0x8004"
|
||||
},
|
||||
"random": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkmoney": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"getpokenewsactive": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkplayergender": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkcoins": {
|
||||
"var_name_arg_position": 0
|
||||
},
|
||||
"addcoins": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"removecoins": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"dowildbattle": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"checkmodernfatefulencounter": {
|
||||
"var_name": "VAR_RESULT"
|
||||
},
|
||||
"msgbox": {
|
||||
"var_name": "VAR_RESULT"
|
||||
}
|
||||
}
|
||||
}
|
348
external/poryscript/font_config.json
vendored
Normal file
348
external/poryscript/font_config.json
vendored
Normal file
|
@ -0,0 +1,348 @@
|
|||
{
|
||||
"defaultFontId": "1_latin_rse",
|
||||
"fonts": {
|
||||
"1_latin_rse": {
|
||||
"maxLineLength": 208,
|
||||
"numLines": 2,
|
||||
"cursorOverlapWidth": 0,
|
||||
"widths": {
|
||||
" ": 3,
|
||||
"À": 6,
|
||||
"Á": 6,
|
||||
"Â": 6,
|
||||
"Ç": 6,
|
||||
"È": 6,
|
||||
"É": 6,
|
||||
"Ê": 6,
|
||||
"Ë": 6,
|
||||
"Ì": 6,
|
||||
"Î": 6,
|
||||
"Ï": 6,
|
||||
"Ò": 6,
|
||||
"Ó": 6,
|
||||
"Ô": 6,
|
||||
"Œ": 8,
|
||||
"Ù": 6,
|
||||
"Ú": 6,
|
||||
"Û": 6,
|
||||
"Ñ": 6,
|
||||
"ß": 6,
|
||||
"à": 6,
|
||||
"á": 6,
|
||||
"ç": 6,
|
||||
"è": 6,
|
||||
"é": 6,
|
||||
"ê": 6,
|
||||
"ë": 6,
|
||||
"ì": 6,
|
||||
"î": 6,
|
||||
"ï": 6,
|
||||
"ò": 6,
|
||||
"ó": 6,
|
||||
"ô": 6,
|
||||
"œ": 8,
|
||||
"ù": 6,
|
||||
"ú": 6,
|
||||
"û": 6,
|
||||
"ñ": 6,
|
||||
"º": 6,
|
||||
"ª": 6,
|
||||
"{SUPER_ER}": 9,
|
||||
"&": 7,
|
||||
"+": 6,
|
||||
"LV": 10,
|
||||
"=": 8,
|
||||
";": 3,
|
||||
"¿": 6,
|
||||
"¡": 4,
|
||||
"{PK}": 8,
|
||||
"{PKMN}": 16,
|
||||
"{POKEBLOCK}": 35,
|
||||
"Í": 6,
|
||||
"%": 6,
|
||||
"(": 4,
|
||||
")": 4,
|
||||
"â": 6,
|
||||
"í": 6,
|
||||
"{UNK_SPACER}": 6,
|
||||
"{UP_ARROW}": 7,
|
||||
"{DOWN_ARROW}": 7,
|
||||
"{LEFT_ARROW}": 7,
|
||||
"{RIGHT_ARROW}": 7,
|
||||
"{SUPER_E}": 6,
|
||||
"<": 6,
|
||||
">": 6,
|
||||
"{SUPER_RE}": 8,
|
||||
"0": 6,
|
||||
"1": 6,
|
||||
"2": 6,
|
||||
"3": 6,
|
||||
"4": 6,
|
||||
"5": 6,
|
||||
"6": 6,
|
||||
"7": 6,
|
||||
"8": 6,
|
||||
"9": 6,
|
||||
"!": 4,
|
||||
"?": 6,
|
||||
".": 3,
|
||||
"-": 6,
|
||||
"·": 3,
|
||||
"…": 6,
|
||||
"“": 6,
|
||||
"”": 6,
|
||||
"‘": 3,
|
||||
"'": 3,
|
||||
"♂": 6,
|
||||
"♀": 6,
|
||||
"¥": 6,
|
||||
",": 3,
|
||||
"×": 7,
|
||||
"/": 6,
|
||||
"A": 6,
|
||||
"B": 6,
|
||||
"C": 6,
|
||||
"D": 6,
|
||||
"E": 6,
|
||||
"F": 6,
|
||||
"G": 6,
|
||||
"H": 6,
|
||||
"I": 6,
|
||||
"J": 6,
|
||||
"K": 6,
|
||||
"L": 6,
|
||||
"M": 6,
|
||||
"N": 6,
|
||||
"O": 6,
|
||||
"P": 6,
|
||||
"Q": 6,
|
||||
"R": 6,
|
||||
"S": 6,
|
||||
"T": 6,
|
||||
"U": 6,
|
||||
"V": 6,
|
||||
"W": 6,
|
||||
"X": 6,
|
||||
"Y": 6,
|
||||
"Z": 6,
|
||||
"a": 6,
|
||||
"b": 6,
|
||||
"c": 6,
|
||||
"d": 6,
|
||||
"e": 6,
|
||||
"f": 6,
|
||||
"g": 6,
|
||||
"h": 6,
|
||||
"i": 4,
|
||||
"j": 5,
|
||||
"k": 6,
|
||||
"l": 4,
|
||||
"m": 6,
|
||||
"n": 6,
|
||||
"o": 6,
|
||||
"p": 6,
|
||||
"q": 6,
|
||||
"r": 5,
|
||||
"s": 6,
|
||||
"t": 6,
|
||||
"u": 6,
|
||||
"v": 6,
|
||||
"w": 6,
|
||||
"x": 6,
|
||||
"y": 6,
|
||||
"z": 6,
|
||||
"▶": 8,
|
||||
":": 5,
|
||||
"Ä": 6,
|
||||
"Ö": 6,
|
||||
"Ü": 6,
|
||||
"ä": 6,
|
||||
"ö": 6,
|
||||
"ü": 6,
|
||||
"{TALL_PLUS}": 0,
|
||||
"{PLAYER}": 56,
|
||||
"{STR_VAR_1}": 80,
|
||||
"{STR_VAR_2}": 80,
|
||||
"{STR_VAR_3}": 80,
|
||||
"{KUN}": 0,
|
||||
"{RIVAL}": 56,
|
||||
"{VERSION}": 56,
|
||||
"{AQUA}": 24,
|
||||
"{MAGMA}": 30,
|
||||
"{ARCHIE}": 36,
|
||||
"{MAXIE}": 30,
|
||||
"{KYOGRE}": 36,
|
||||
"{GROUDON}": 42,
|
||||
"$": 0
|
||||
}
|
||||
},
|
||||
"1_latin_frlg": {
|
||||
"maxLineLength": 208,
|
||||
"numLines": 2,
|
||||
"cursorOverlapWidth": 10,
|
||||
"widths": {
|
||||
" ": 6,
|
||||
"À": 6,
|
||||
"Á": 6,
|
||||
"Â": 6,
|
||||
"Ç": 6,
|
||||
"È": 6,
|
||||
"É": 6,
|
||||
"Ê": 6,
|
||||
"Ë": 6,
|
||||
"Ì": 6,
|
||||
"Î": 6,
|
||||
"Ï": 6,
|
||||
"Ò": 6,
|
||||
"Ó": 6,
|
||||
"Ô": 6,
|
||||
"Œ": 8,
|
||||
"Ù": 6,
|
||||
"Ú": 6,
|
||||
"Û": 6,
|
||||
"Ñ": 6,
|
||||
"ß": 6,
|
||||
"à": 6,
|
||||
"á": 6,
|
||||
"ç": 6,
|
||||
"è": 6,
|
||||
"é": 6,
|
||||
"ê": 6,
|
||||
"ë": 6,
|
||||
"ì": 6,
|
||||
"î": 6,
|
||||
"ï": 6,
|
||||
"ò": 6,
|
||||
"ó": 6,
|
||||
"ô": 6,
|
||||
"œ": 8,
|
||||
"ù": 6,
|
||||
"ú": 6,
|
||||
"û": 6,
|
||||
"ñ": 6,
|
||||
"º": 6,
|
||||
"ª": 6,
|
||||
"{SUPER_ER}": 9,
|
||||
"&": 8,
|
||||
"+": 8,
|
||||
"LV": 10,
|
||||
"=": 8,
|
||||
";": 5,
|
||||
"¿": 6,
|
||||
"¡": 6,
|
||||
"{PK}": 8,
|
||||
"{PKMN}": 16,
|
||||
"{POKEBLOCK}": 36,
|
||||
"Í": 6,
|
||||
"%": 8,
|
||||
"(": 5,
|
||||
")": 5,
|
||||
"â": 6,
|
||||
"í": 6,
|
||||
"{UP_ARROW}": 12,
|
||||
"{DOWN_ARROW}": 12,
|
||||
"{LEFT_ARROW}": 12,
|
||||
"{RIGHT_ARROW}": 12,
|
||||
"{SUPER_E}": 8,
|
||||
"<": 8,
|
||||
">": 8,
|
||||
"{SUPER_RE}": 8,
|
||||
"0": 6,
|
||||
"1": 6,
|
||||
"2": 6,
|
||||
"3": 6,
|
||||
"4": 6,
|
||||
"5": 6,
|
||||
"6": 6,
|
||||
"7": 6,
|
||||
"8": 6,
|
||||
"9": 6,
|
||||
"!": 6,
|
||||
"?": 6,
|
||||
".": 5,
|
||||
"-": 6,
|
||||
"·": 5,
|
||||
"…": 6,
|
||||
"“": 6,
|
||||
"”": 6,
|
||||
"‘": 3,
|
||||
"'": 3,
|
||||
"♂": 6,
|
||||
"♀": 6,
|
||||
"¥": 8,
|
||||
",": 5,
|
||||
"×": 8,
|
||||
"/": 6,
|
||||
"A": 6,
|
||||
"B": 6,
|
||||
"C": 6,
|
||||
"D": 6,
|
||||
"E": 6,
|
||||
"F": 6,
|
||||
"G": 6,
|
||||
"H": 6,
|
||||
"I": 6,
|
||||
"J": 6,
|
||||
"K": 6,
|
||||
"L": 6,
|
||||
"M": 6,
|
||||
"N": 6,
|
||||
"O": 6,
|
||||
"P": 6,
|
||||
"Q": 6,
|
||||
"R": 6,
|
||||
"S": 6,
|
||||
"T": 6,
|
||||
"U": 6,
|
||||
"V": 6,
|
||||
"W": 6,
|
||||
"X": 6,
|
||||
"Y": 6,
|
||||
"Z": 6,
|
||||
"a": 6,
|
||||
"b": 6,
|
||||
"c": 6,
|
||||
"d": 6,
|
||||
"e": 6,
|
||||
"f": 5,
|
||||
"g": 6,
|
||||
"h": 6,
|
||||
"i": 4,
|
||||
"j": 6,
|
||||
"k": 5,
|
||||
"l": 5,
|
||||
"m": 6,
|
||||
"n": 5,
|
||||
"o": 6,
|
||||
"p": 6,
|
||||
"q": 6,
|
||||
"r": 5,
|
||||
"s": 5,
|
||||
"t": 5,
|
||||
"u": 6,
|
||||
"v": 6,
|
||||
"w": 6,
|
||||
"x": 6,
|
||||
"y": 6,
|
||||
"z": 6,
|
||||
"▶": 8,
|
||||
":": 5,
|
||||
"Ä": 6,
|
||||
"Ö": 6,
|
||||
"Ü": 6,
|
||||
"ä": 6,
|
||||
"ö": 6,
|
||||
"ü": 6,
|
||||
"{TALL_PLUS}": 0,
|
||||
"{PLAYER}": 56,
|
||||
"{STR_VAR_1}": 80,
|
||||
"{STR_VAR_2}": 80,
|
||||
"{STR_VAR_3}": 80,
|
||||
"{KUN}": 0,
|
||||
"{RIVAL}": 56,
|
||||
"{VERSION}": 56,
|
||||
"$": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
external/poryscript/poryscript
vendored
Executable file
BIN
external/poryscript/poryscript
vendored
Executable file
Binary file not shown.
1
rom.sha1
1
rom.sha1
|
@ -1 +0,0 @@
|
|||
f3ae088181bf583e55daf962a92bb46f4f1d07b7 pokeemerald.gba
|
Loading…
Reference in a new issue