chore: initial commit

This commit is contained in:
Anna 2022-03-05 18:26:14 -05:00
commit 8ee38dfc1d
Signed by: anna
GPG Key ID: 0B391D8F06FCD9E0
9 changed files with 2321 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

398
Cargo.lock generated Normal file
View File

@ -0,0 +1,398 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "crossbeam-channel"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9"
dependencies = [
"cfg-if",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "ffxii-tza-auto-notes"
version = "0.1.0"
dependencies = [
"anyhow",
"itertools",
"lazy_static",
"maplit",
"process_list",
"serde",
"serde_yaml",
"sysinfo",
"vmemory",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
"either",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "nix"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
dependencies = [
"bitflags",
"cc",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
name = "ntapi"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97ba11b4249e387303cc3a41ac79d7bdf8382ad72b64621a77bac197b75a73e2"
dependencies = [
"winapi",
]
[[package]]
name = "ntapi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
dependencies = [
"winapi",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
[[package]]
name = "process_list"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1132b222742f1d1bbe2078836970d9eac85cb354076b58534edc29aa14668ff0"
dependencies = [
"winapi",
]
[[package]]
name = "quote"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "ryu"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_yaml"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0"
dependencies = [
"indexmap",
"ryu",
"serde",
"yaml-rust",
]
[[package]]
name = "syn"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "sysinfo"
version = "0.23.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07fa4c84a5305909b0eedfcc8d1f2fafdbede645bb700a45ecaafe681a0ac5d6"
dependencies = [
"cfg-if",
"core-foundation-sys",
"libc",
"ntapi 0.3.7",
"once_cell",
"rayon",
"winapi",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "vmemory"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe1e3c3facc6d67d5972f73b14189930ca96cd3ec4f7df151863f4377480e8c0"
dependencies = [
"mach",
"nix",
"ntapi 0.2.0",
"winapi",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

17
Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "ffxii-tza-auto-notes"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1"
vmemory = "0.1"
sysinfo = "0.23"
process_list = "0.2"
itertools = "0.10"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
maplit = "1"
lazy_static = "1"

841
notes.yaml Normal file
View File

@ -0,0 +1,841 @@
steps:
# 0: title screen/into cutscenes
- stage: 0
areas:
# 274: aerial gardens
- area: 274
steps: |-
- **Skip**: 3
# 13: control of reks
- stage: 13
areas:
# 274: aerial gardens
- area: 274
steps: |-
- Talk to Basch and the soldier
- Open the gate
# 16: gone through gate
- stage: 16
areas:
# 275: inner ward
- area: 275
steps: |-
- Menu
1. Active
2. Battle speed: fast
3. Cursor position: last selection
- **Skip**: 1
- Kill Remora with Thunder spam
- **Skip**: 1
- Go upstairs
# 19: after door after remora
- stage: 19
areas:
# 279: lower apartments
- area: 279
steps: |-
- **Skip**: 1
- Go forward and up the stairs to save crystal
# 21: after save tutorial cutscene
- stage: 21
areas:
# 279: lower apartments
# 280: upper apartments
# 282: the highhall
- area: 280
steps: |-
- Go upstairs
- **Skip**: 1
- Kill the guards
- Go into throne room
- **Skip**: 3
# 22: reks decides to kill swordsmen
# 23: swordsmen dead
# 25: control of vaan
- stage: 25
areas:
# 1145: overflow cloaca
- area: 1145
steps: |-
- Kill rats
- **Skip**: 3
# 35: map tutorial opens
# 40: control of vaan after rat slaughter
- stage: 40
areas:
# 291: east end
- area: 291
steps: |-
- South to item shop
- **Skip**: 1
# 45: after item shop cutscene
- stage: 45
areas:
# 291: east end
# 304: the sandsea
- area: 291
steps: |-
- North to Sandsea
- area: 304
steps: |-
- **Skip**: 1
- Choose not to hear the details
- Choose not to repeat the message
# 65: control of vaan after picking up rogue tomato
- stage: 65
areas:
# 304: the sandsea
# 291: east end
# 292: southern plaza
- area: 304
steps: |-
- Exit
- area: 291
steps: |-
- Go South
- Exit across from item shop
- area: 292
steps: |-
- Go to East Gate
- **Skip**: 1
# 68: after east gate cutscene
- stage: 68
areas:
# 305: eastgate
# 227: the stepping
- area: 305
steps: |-
- Enter the Estersand
- area: 227
steps: |-
- **Skip**: 1
- Straight ahead to Rogue Tomato
- Attack, follow, attack
- **Skip**: 1
# 78: killed rogue tomato
- stage: 78
areas:
# 227: the stepping
# 305: eastgate
- area: 227
steps: |-
- Return to Rabanastre
- area: 305
steps: |-
- Talk to Kytes
- **Skip**: 3
# 85: after first cutscene
# 100: after second cutscene
# 105: control of vaan after talking to kytes
- stage: 105
areas:
# 289: north end
# 701: north sprawl
# 702: south sprawl
# 703: dalan's house
- area: 289
steps: |-
- Go straight into Lowtown
- area: 701
steps: |-
- Exit South
- area: 702
steps: |-
- South then west to Dalan
- **Skip**: 1
# 120: after cutscene, talking to dalan
- stage: 120
areas:
# 703: dalan's house
# 702: south sprawl
# 306: southgate
# 236: throne road (dry)
# 243: nomad village (dry)
- area: 703
steps: |-
- Exit
- area: 702
steps: |-
- Exit right to Southgate
- area: 306
steps: |-
- Exit left to Giza
- area: 236
steps: |-
- **Skip**: 1
- Straight ahead to camp
- area: 243
steps: |-
- Talk to lady by sunstone
- **Skip**: 1
# 125: cutscene after talking to sunstone lady
# 130: control after penelo joins party
- stage: 130
areas:
# 243: nomad village (dry)
- area: 243
steps: |-
- Exit West
# 140: after exiting camp and listening to penelo
- stage: 140
areas:
# 239: toam hills (dry)
# 247: starfall field (dry)
- area: 239
steps: |-
- Exit South
- area: 247
steps: |-
- Quit to title
- stage: 0
areas:
# 12: main menu
- area: 12
steps: |-
- Trial mode
- stage: 140
areas:
# 1155: stage 1
# 1166: stage 2
- area: 1155
steps: |-
- Grab Diamond Armlet, kill rats
- area: 1166
steps: |-
- Quit to title
- stage: 0
areas:
# 12: main menu
- area: 12
steps: |-
- Load autosave
- stage: 140
areas:
# 247: starfall field (dry)
# 248: crystal glade (dry)
- area: 247
steps: |-
- Exit Southeast to Jinn
- area: 248
steps: |-
- Talk to Jinn
# 145: after talking to jinn
- stage: 145
areas:
# 248: crystal glade (dry)
# 247: starfall field (dry)
# 249: gizas south bank (dry)
# 228: yardang labyrinth
# 630: west barbican
- area: 248
steps: |-
- Exit West
- area: 247
steps: |-
- Use West sunstone
- Exit East back to Jinn
- area: 248
steps: |-
- Exit East
- area: 249
steps: |-
- Exit Northeast towards Nalbina
- area: 228
steps: |-
- Go northeast, then north, exit to Nalbina
- area: 630
steps: |-
- Shop:
1. Sell Diamond Armlet
2. Buy 11x Phoenix Down
- Return to Giza
- area: 249
steps: |-
- Use sunstone
- Exit North
- area: 0
steps: |-
- Use Northwest sunstone
# 160: after getting sunstone
- stage: 160
areas:
# 243: nomad village (dry)
# 236: throne road (dry)
# 306: southgate
# 292: southern plaza
# 307: westgate
# 345: galtea downs
# 306: southgate
# 702: south sprawl
- area: 243
steps: |-
- Shop:
1. Buy Dark
- Exit North
- area: 236
steps: |-
- Exit North to Rabanastre
- area: 306
steps: |-
- Exit North
- area: 292
steps: |-
- Exit West to Westgate
- area: 307
steps: |-
- Exit to Westersand
- area: 345
steps: |-
- **Skip**: 1
- Northeast, stop before zoning
- Get Vaan to critical HP
![vaan dustia hp chart](./img/vaan_dustia_hp_chart.png)
- Kill Penelo, set battle speed to slow
- Exit, spawn Dustia, use Phoenix Down to kill
- Kill 12 times total, until level 13 Vaan
- Return to Rabanastre
- area: 307
steps: |-
- Exit
- area: 292
steps: |-
- Exit South to Southgate
- area: 306
steps: |-
- West to Lowtown
- area: 702
steps: |-
- West to Dalan's place
- **Skip**: 1
# 170: penelo leaves party, control in dalan's house
- stage: 170
areas:
# 703: dalan's house
- area: 703
steps: |-
- Talk to Dalan
- **Skip**: 1
# 175: obtain crescent stone, control in dalan's house
- stage: 175
areas:
# 703: dalan's house
# 312: east waterway control (cutscene)
- area: 703
steps: |-
- Exit
- area: 312
steps: |-
- **Skip**: 1
# 180: after leaving dalan's house with crescent stone
- stage: 180
areas:
# 702: south sprawl
# 701: north sprawl
# 311: central spur stairs
# 315: northern sluiceway
# 313: north spur sluiceway
# 567: cellar stores
- area: 702
steps: |-
- Exit North
- area: 701
steps: |-
- North and West to Garamsythe
- Enter unlocked door
- area: 311
steps: |-
- **Skip**: 1
- Exit West
- area: 315
steps: |-
- North, East, exit North
- area: 313
steps: |-
- West until North stairs
# 190: after going up stairs, fireworks fmv
- stage: 190
# 576: invitation to heresy (cutscene)
areas:
- area: 576
steps: |-
- **Skip**: 2
# 200: after fireworks fmv, control in palace
- stage: 200
areas:
# 567: cellar stores
# 568: cellars
# 569: lower halls
- area: 567
steps: |-
- Exit
- area: 568
steps: |-
- Go straight
- Get East-most (left) chest for Elixir
- North for cutscene
- Approach guard for cutscene
- Talk to servant, shout
- Exit upstairs
- area: 569
steps: |-
- Straight, South, East, shout at intersection
- West, North, shout at intersection
- East, North, West, use
- West, shout at intersection
- East, North, West to exit at wall
# 210: after entering secret chamber
- stage: 210
areas:
# 570: secret passage
- area: 570
steps: |-
- Use switch on back left wall
- Open door
- **Skip**: 1
# 215: gone through hidden door
# 220: you obtain the goddess's magicite
- stage: 220
areas:
# 572: the garden stairs
- area: 0
steps: |-
- **Skip**: 1
- Exit upstairs
- **Skip**: 2
# 225: after fmv
# 235: control in garamsythe
- stage: 235
areas:
# 314: east spur stairs
- area: 314
steps: |-
- Go down the stairs
- Gambit tutorial
# 244: after gambit tutorial
- stage: 244
areas:
# 314: east spur stairs
# 316: east waterway control
# 318: no. 11 channel
# 319: east sluice control
- area: 314
steps: |-
- Menu:
1. Licence boards
- All: Red battlemage
2. Licences
- All: Dark
3. Gambits
- Vaan, Fran: turn on gambits, highest hp: Dark
- Balthier: HP < 50%: Potion, highest hp: Dark
4. Config
- Battle speed: fast
- Exit ahead
- area: 316
steps: |-
- West (no stairs), South to exit
- area: 318
steps: |-
- Follow path South, take branch, exit South
- area: 319
steps: |-
- Follow path South to downstairs
- **Skip**: 1
- **Boss**: gambit to win
- **Skip**: 1
# 257: before ashe cutscene
- stage: 257
areas:
# 319: east sluice control
- area: 319
steps: |-
- Approach Ashe
- **Skip**: 1
# 260: amalia joins
- stage: 260
areas:
# 319: east sluice control
# 326: southern sluiceway
- area: 319
steps: |-
- Exit ahead
- area: 326
steps: |-
- Walk ahead
- **Skip**: 1
- **Boss**: gambit to win
- **Skip**: 1
# 265: after flan boss
- stage: 265
areas:
# 326: southern sluiceway
# 320: west sluice control
# 321: no. 10 channel
# 322: central waterway control
# 329: overflow cloaca
- area: 326
steps: |-
- Exit Northwest
- area: 320
steps: |-
- South, West, North, exit
- area: 321
steps: |-
- North, East, North, exit
- area: 322
steps: |-
- Through gate
- area: 329
steps: |-
- **Skip**: 1
- **Boss**: flee to the left in the water, gambit to win
- **Skip**: 4
# 285: after post-firemane cutscene
# 290: next cutscene
# 301: next cutscene
# 303: control in nalbina dungeon
- stage: 303
areas:
# 48: stockade
# 49: arena
# 710: the confiscatory
- area: 48
steps: |-
- East, then North and exit near Save Crystal
- area: 49
steps: |-
- **Skip**: 1
- **Boss**: gambits to win
- **Skip**: 1
- area: 710
steps: |-
- Walk forward
- **Skip**: 1
# 310: control after getting equipment back
- stage: 310
areas:
# 710: the confiscatory
# 709: the black watch
- area: 710
steps: |-
- Exit East
- area: 709
steps: |-
- **Skip**: 1
- Go all the way North, then West
- **Skip**: 1
- Exit ahead
- **Skip**: 3
# 312: cutscene
# 315: after judges open door
# 316: next cutscene
# 317: control in barheim
- stage: 317
areas:
# 53: the lightworks
- area: 53
steps: |-
- Down the stairs, East, grab (left) chest for gil
- Touch device
- Continue down stairs, talk to shopkeep
# 319: get fuse
- stage: 319
areas:
# 53: the lightworks
- area: 53
steps: |-
- Have Vaan potion, pilot someone else to device
- Install fuse
# 321: used fuse
- stage: 321
areas:
# 53: the lightworks
# 58: op sector 29
- area: 53
steps: |-
- Switch back to Vaan, use device
- Exit
- area: 58
steps: |-
- **Skip**: 1
# 323: after mimic cutscene
- stage: 323
areas:
# 58: op sector 29
# 54: great eastern passage
# 56: special op sector 3
# 57: op sector 37
# 66: north-south junction
- area: 58
steps: |-
- Follow path South
- Kill mimics stealing charge
- Exit East
- area: 54
steps: |-
- Kill mimic stealing charge
- Follow path south, killing big mimics
- Left path
- Right path
- Exit South
- area: 56
steps: |-
- West, kill big mimic
- East, North
- Exit West
- area: 57
steps: |-
- Use switchboard
- South, kill mimic, West, exit way you came
- area: 56
steps: |-
- East, exit South (kill mimic)
- area: 66
steps: |-
- **Skip**: 3
# 333: after basch cutscenes
- stage: 333
areas:
# 66: north-south junction
# 61: great central passage
# 62: the zeviah subterrane
# 70: terminus no. 4 adjunct
# 69: terminus no. 4
- area: 66
steps: |-
- Exit South
- area: 61
steps: |-
- Exit South
- area: 62
steps: |-
- South, loop North (kill mimics as necessary)
- Exit East
- area: 70
steps: |-
- Exit South
- area: 69
steps: |-
- **Skip**: 1
- **Boss**: gambit to win
- **Skip**: 1
# 340: mimic queen cutscene
# 341: post-mimic queen (to think dalmascan air could taste so sweet)
- stage: 341
areas:
# 231: passage entrance
- area: 231
steps: |-
- Unskippable cutscene
# 343: after dalmascan air tastes so sweet
- stage: 343
areas:
# 231: passage entrance
# 229: sand-swept naze
# 228: yardang labyrinth
# 630: west barbican
# 306: southgate
- area: 231
steps: |-
- Exit towards camera
- area: 229
steps: |-
- West-by-northwest, follow path, exit South
- area: 228
steps: |-
- South, loop East, exit North to Nalbina
- area: 630
steps: |-
- Teleport to Rabanastre
- area: 306
steps: |-
- **Skip**: 1
# 350: control after balthier and fran leave
- stage: 350
areas:
# 306: southgate
# 702: south sprawl
# 703: dalan's house
- area: 306
steps: |-
- East to enter Lowtown
- area: 702
steps: |-
- Enter Dalan's house
- area: 703
steps: |-
- Talk to Dalan
- **Skip**: 1
# 375: after getting sword from dalan
- stage: 375
areas:
# 703: dalan's house
# 702: south sprawl
# 701: north sprawl
- area: 703
steps: |-
- Exit
- area: 702
steps: |-
- Exit North
- area: 701
steps: |-
- Cross over West, go West to hideout
- **Skip**: 2
# 386: after first cutscene
# 390: control after basch joins
- stage: 390
areas:
# 701: north sprawl
# 291: east end
- area: 701
steps: |-
- Back across to the East
- East at intersection
- Exit North
- area: 291
steps: |-
- North
- **Skip**: 1
# 400: after basch cutscene outside sandsea
- stage: 400
areas:
# 291: east end
# 304: the sandsea
- area: 291
steps: |-
- Enter the Sandsea
- area: 304
steps: |-
- Go upstairs
- **Skip**: 1
# 420: after balthier cutscene in sandsea
- stage: 420
areas:
# 304: the sandsea
# 291: east end
# 307: westgate
# 788: aerodrome (rabanastre)
- area: 304
steps: |-
- Exit
- area: 291
steps: |-
- Moogling to Westgate
- area: 307
steps: |-
- Enter Aerodrome
- area: 788
steps: |-
- Straight back and talk to Balthier
- **Skip**: 3
# 460: strahl cutscene
# 520: clouds cutscene
# 546: control in bhujerba
- stage: 546
areas:
# 791: aerodrome (bhujerba)
# 803: travica way
- area: 791
steps: |-
- Exit ahead
- area: 803
steps: |-
- **Skip**: 1
# 550: larsa joins
- stage: 550
areas:
# 803: travica way
# 805: miners' end
# 806: lhusu square
- area: 803
steps: |-
- East, South, exit East
- area: 805
steps: |-
- East, exit North
- area: 806
steps: |-
- Go downstairs
- **Skip**: 1
# 580: control in lhusu
- stage: 580
areas:
# 357: shaft entry
- area: 357
steps: |-
- Go downstairs
- **Skip**: 1
# 610: control after cutscene
- stage: 610
areas:
# 357: shaft entry
# 358: oltam span
# 359: transitway 1
# 365: shunia twinspan
# 933: site 2
- area: 357
steps: |-
- North, West, second South, exit West
- area: 358
steps: |-
- Exit ahead
- area: 359
steps: |-
- Exit North
- area: 365
steps: |-
- Exit ahead
- area: 933
steps: |-
- East, follow South path to caves
- **Skip**: 1
# 645: fleeing
- stage: 645
areas:
# 933: site 2
# 934: shunia twinspan
# 935: transitway 1
# 936: oltam span
# 357: shaft entry
- area: 933
steps: |-
- South, exit West
- area: 934
steps: |-
- Exit ahead
- area: 935
steps: |-
- South, East, exit East
- area: 936
steps: |-
- Exit ahead
- area: 357
steps: |-
- **Skip**: 1
# 660: escaped
- stage: 660
areas:
# 357: shaft entry
# 806: lhusu square
- area: 357
steps: |-
- North, East, South to exit
- area: 806
steps: |-
- **Skip**: 1
# 680: after lhusu 1
- stage: 680
areas:
# 806: lhusu square
- area: 806
steps: |-
- Upstairs
- **Skip**: 1
# 710: I'm Captain Basch!
- stage: 710
areas:
# 806: lhusu square
- area: 806
steps: |-
- bruh idk lmao

98
src/game_state.rs Normal file
View File

@ -0,0 +1,98 @@
use anyhow::{Context, Result};
use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, RefreshKind, System, SystemExt};
use vmemory::ProcessMemory;
pub struct GameState {
pub story: u16,
pub location: u16,
pid: u32,
base: usize,
base_size: usize,
mem: Vec<u8>,
proc_mem: ProcessMemory,
story_pattern: Vec<u8>,
location_pattern: Vec<u8>,
}
impl GameState {
pub fn new() -> Result<Self> {
let mut sys = System::new_with_specifics(RefreshKind::new().with_processes(ProcessRefreshKind::new()));
let proc = sys.processes()
.iter()
.find(|(_, proc)| proc.name() == "FFXII_TZA.exe");
let (pid, _) = match proc {
Some(p) => p,
None => anyhow::bail!("could not find TZA process")
};
let mem = ProcessMemory::attach_process(pid.as_u32()).unwrap();
let mut base = 0;
let mut base_size = 0;
process_list::for_each_module(pid.as_u32(), |(address, size), name| {
let stem = name.file_stem().unwrap_or_default();
if stem == "FFXII_TZA" {
base = address;
base_size = size;
}
}).context("could not loop TZA modules")?;
if base == 0 || base_size == 0 {
anyhow::bail!("could not find TZA base address");
}
let tza_mem = mem.read_memory(base, base_size, false);
let story_ptr_pattern = crate::util::parse_pattern("48 8B 05 ?? ?? ?? ?? 48 85 C0 74 03 66 89 08 C3").unwrap();
let location_pattern = crate::util::parse_pattern("8B 0D ?? ?? ?? ?? FF D0 4C 89 3D ?? ?? ?? ?? 48 83 C4 30 41 5F C3").unwrap();
Ok(Self {
story: 0,
location: 0,
pid: pid.as_u32(),
base,
base_size,
mem: tza_mem,
proc_mem: mem,
story_pattern: story_ptr_pattern,
location_pattern,
})
}
pub fn refresh(&mut self) -> Result<()> {
let story_ptr_ptr = match crate::util::find_pattern(&self.mem, &self.story_pattern) {
Some(ptr) => ptr,
None => anyhow::bail!("could not find story pointer"),
};
let location_ptr = match crate::util::find_pattern(&self.mem, &self.location_pattern) {
Some(ptr) => ptr,
None => anyhow::bail!("could not find location pointer"),
};
let story_ptr_offset = match crate::util::get_static_address(&self.mem, story_ptr_ptr, self.base) {
Some(addr) => addr,
None => anyhow::bail!("could not find story pointer offset"),
};
let location_ptr_offset = match crate::util::get_static_address(&self.mem, location_ptr, self.base) {
Some(addr) => addr,
None => anyhow::bail!("could not find location pointer offset"),
};
let story_ptr_array: [u8; 8] = self.mem[story_ptr_offset..story_ptr_offset + 8].try_into().unwrap();
let story_ptr = u64::from_le_bytes(story_ptr_array) as usize - self.base;
let story_vec = self.proc_mem.read_memory(self.base + story_ptr, 2, false);
let story_array: [u8; 2] = story_vec.try_into().map_err(|_| anyhow::anyhow!("not enough story bytes"))?;
self.story = u16::from_le_bytes(story_array);
let location_vec = self.proc_mem.read_memory(self.base + location_ptr_offset, 2, false);
let location_array: [u8; 2] = location_vec.try_into().map_err(|_| anyhow::anyhow!("not enough location bytes"))?;
self.location = u16::from_le_bytes(location_array);
Ok(())
}
pub fn location_name(&self) -> Option<&'static str> {
crate::util::LOCATIONS.get(&self.location).map(std::ops::Deref::deref)
}
}

76
src/main.rs Normal file
View File

@ -0,0 +1,76 @@
use anyhow::Result;
use std::fs::File;
use std::thread;
use crate::notes::Notes;
use crate::game_state::GameState;
use crate::notes_state::NotesState;
mod notes;
mod game_state;
mod notes_state;
mod util;
fn main() -> Result<()> {
let notes: Notes = serde_yaml::from_reader(File::open("notes.yaml")?)?;
let mut game_state = GameState::new()?;
let mut notes_state = NotesState::new(&notes, &mut game_state)?;
println!("Ready");
// let mut first = true;
// let mut last_story = 0;
// let mut last_location = 0;
// let mut last_printed_location = 0;
// let mut step_idx = 23;
// let mut area_idx = 0;
// let mut current_step = &notes.steps[0];
// let mut force_instructions = false;
loop {
notes_state.tick(&mut game_state)?;
thread::sleep(std::time::Duration::from_millis(16));
// last_story = state.story;
// last_location = state.location;
// state.refresh()?;
//
// if last_story != state.story {
// let next_step = match notes.steps.get(step_idx) {
// Some(step) => step,
// None => continue,
// };
//
// if next_step.stage == state.story {
// current_step = next_step;
// step_idx += 1;
// area_idx = 0;
// force_instructions = current_step.areas[0].area == 0 || current_step.areas[0].area == last_location;
// }
// }
//
// if force_instructions || last_location != state.location {
// let next_area = match current_step.areas.get(area_idx) {
// Some(area) => area,
// None => continue,
// };
//
// if next_area.area == state.location || next_area.area == 0 {
// if first {
// first = false;
// step_idx += 1;
// }
//
// area_idx += 1;
// force_instructions = false;
// if last_printed_location != next_area.area {
// println!("{}", state.location_name().unwrap_or("Unknown Location"));
// last_printed_location = state.location;
// }
//
// println!("{}", next_area.steps);
// }
// }
}
Ok(())
}

18
src/notes.rs Normal file
View File

@ -0,0 +1,18 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Notes {
pub steps: Vec<Step>,
}
#[derive(Debug, Deserialize)]
pub struct Step {
pub stage: u16,
pub areas: Vec<Area>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct Area {
pub area: u16,
pub steps: String,
}

111
src/notes_state.rs Normal file
View File

@ -0,0 +1,111 @@
use anyhow::Result;
use crate::{GameState, Notes};
use crate::notes::{Area, Step};
pub struct NotesState<'a> {
notes: &'a Notes,
last_printed_location: u16,
last_stage: u16,
last_location: u16,
step_idx: usize,
area_idx: usize,
current_step: &'a Step,
first_step: bool,
force_print: bool,
}
impl<'a> NotesState<'a> {
pub fn new(notes: &'a Notes, game: &mut GameState) -> Result<Self> {
game.refresh()?;
// find first step with a matching story stage
let steps = notes.steps
.iter()
.take_while(|step| step.stage <= game.story)
.count();
let (step, step_idx, force) = if steps <= 1 {
// nothing previous OR first step
(&notes.steps[0], 0, false)
} else {
// in progress
(&notes.steps[steps - 1], steps - 1, true)
};
// find first area that matches
let area_idx = step.areas
.iter()
.position(|area| area.area == 0 || area.area == game.location)
.unwrap_or(0);
Ok(Self {
notes,
last_printed_location: 0,
last_stage: 0,
last_location: 0,
step_idx,
area_idx,
current_step: step,
first_step: true,
force_print: force,
})
}
pub fn tick(&mut self, game: &mut GameState) -> Result<()> {
self.last_stage = game.story;
self.last_location = game.location;
game.refresh()?;
let stage_changed = self.last_stage != game.story;
let location_changed = self.last_location != game.location;
let step_advanced = stage_changed && self.change_step(game);
let area = match self.area() {
Some(area) => area.clone(),
None => return Ok(()),
};
if self.force_print || ((step_advanced || location_changed) && (game.location == area.area || area.area == 0)) {
if self.last_printed_location != game.location {
self.last_printed_location = game.location;
println!("{}", game.location_name().unwrap_or("Unknown Location"))
}
println!("{}", area.steps);
self.area_idx += 1;
if self.first_step {
self.first_step = false;
self.step_idx += 1;
if !self.force_print {
self.area_idx = 0;
}
}
if self.force_print {
self.force_print = false;
}
}
Ok(())
}
fn area(&self) -> Option<&Area> {
self.current_step.areas.get(self.area_idx)
}
fn change_step(&mut self, game: &mut GameState) -> bool {
let next = match self.notes.steps.get(self.step_idx) {
Some(step) => step,
None => return false,
};
if next.stage == game.story {
self.current_step = next;
self.step_idx += 1;
self.area_idx = 0;
return true;
}
false
}
}

761
src/util.rs Normal file
View File

@ -0,0 +1,761 @@
use std::collections::HashMap;
use itertools::Itertools;
pub fn parse_pattern(s: &str) -> Option<Vec<u8>> {
let no_whitespace = s.replace(char::is_whitespace, "");
if no_whitespace.len() % 2 == 1 {
return None;
}
let mut pattern = Vec::with_capacity(no_whitespace.len() / 2);
for mut chunk in &no_whitespace.chars().chunks(2) {
let joined = chunk.join("");
if joined == "??" {
pattern.push(0);
continue;
}
let byte = u8::from_str_radix(&joined, 16).ok()?;
pattern.push(byte);
}
Some(pattern)
}
pub fn find_pattern(mem: &[u8], pattern: &[u8]) -> Option<usize> {
if pattern.len() > mem.len() {
return None;
}
let last = pattern.len() - 1;
let mut offset = 0;
let max_offset = mem.len() - pattern.len();
while offset < max_offset {
let mut position = last;
while pattern[position] == mem[position + offset] || pattern[position] == 0 {
if position == 0 {
return Some(offset);
}
position -= 1;
}
offset += 1;
}
None
}
pub fn get_static_address(mem: &[u8], mut addr: usize, base: usize) -> Option<usize> {
loop {
addr += 1;
if addr + 4 > mem.len() {
return None;
}
let array: [u8; 4] = mem[addr..addr + 4].try_into().unwrap();
let num = i32::from_le_bytes(array) as isize + addr as isize + 4 - base as isize;
if num > mem.len() as isize || num < 0 {
continue;
}
let offset = addr as isize + i32::from_le_bytes(array) as isize;
return Some(offset as usize + 4);
}
}
lazy_static::lazy_static! {
pub static ref LOCATIONS: HashMap<u16, &'static str> = maplit::hashmap! {
12 => "Main Menu",
13 => "End Credits",
48 => "Stockade",
49 => "Arena",
51 => "Oubliette",
53 => "The Lightworks",
54 => "Great Eastern Passage",
55 => "Op Sector 36",
56 => "Special Op Sector 3",
57 => "Op Sector 37",
58 => "Op Sector 29",
61 => "Great Central Passage",
62 => "The Zeviah Subterrane",
66 => "North-South Junction",
69 => "Terminus No. 4",
70 => "Terminus No. 4 Adjunct",
71 => "Terminus No. 7",
124 => "Observation Parlour",
125 => "Sky Saloon",
126 => "Air Deck",
129 => "South Bank Village",
130 => "North Bank Village",
132 => "The Yoma",
133 => "Broken Sands",
137 => "Uazcuff Hills",
138 => "Sundered Earth",
139 => "The Highlands",
140 => "Fields of Eternity",
141 => "The Shaded Path",
142 => "The Chosen Path",
144 => "The Skytrail",
145 => "Realm of the Elder Dream",
146 => "The Lost Way",
147 => "Garden of Life's Circle",
148 => "Oliphzak Rise",
149 => "The Nameless Spring",
151 => "The Omen-Spur",
152 => "Trunkwall Road",
153 => "Diverging Way",
154 => "Sun-dappled Path",
155 => "Garden of Decay",
156 => "Path of Hours",
157 => "Quietened Trace",
158 => "Grand Bower",
162 => "Corridor of Ages",
163 => "Piebald Path",
167 => "Greencrag",
168 => "The Muted Scarp",
169 => "Vale of Lingering Sorrow",
170 => "Hope's Reach",
171 => "Echoes of the Past",
175 => "The Slumbermead",
176 => "Succor Midst Sorrow",
177 => "The Fog Mutters",
178 => "Overlooking Eternity",
179 => "Lifeless Strand",
180 => "Field of the Fallen Lord",
184 => "Falls of Time",
185 => "Mirror of the Soul",
186 => "The Acolyte's Burden",
187 => "Doubt Abandoned",
188 => "Skybent Chamber",
192 => "Destiny's March",
193 => "Temptation Eluded",
194 => "Chamber of the Chosen",
198 => "Hall of Shadowlight",
200 => "Hall of Lambent Darkness",
202 => "Hall of the Wroth God",
209 => "Southern Skirts",
210 => "Summit Path",
215 => "Rays of Ashen Light",
216 => "Empyrean Way",
217 => "Skyreach Ridge",
218 => "Trail of Sky-flung Stone",
219 => "Northern Skirts",
220 => "Halny Crossing",
223 => "Empyrean Seat",
227 => "The Stepping",
228 => "Yardang Labyrinth",
229 => "Sand-swept Naze",
230 => "Banks of the Nebra",
231 => "Passage Entrance",
232 => "Murmuring Defile",
233 => "Outpost",
236 => "Throne Road",
237 => "Warrior's Wash",
238 => "Gizas North Bank",
239 => "Toam Hills",
243 => "Nomad Village",
247 => "Starfall Field",
248 => "Crystal Glade",
249 => "Gizas South Bank",
253 => "Throne Road",
254 => "Warrior's Wash",
255 => "Gizas North Bank",
256 => "Toam Hills",
260 => "Nomad Village",
264 => "Starfall Field",
265 => "Crystal Glade",
266 => "Gizas South Bank",
270 => "Tracks of the Beast",
274 => "Aerial Gardens",
275 => "Inner Ward",
279 => "Lower Apartments",
280 => "Upper Apartments",
282 => "The Highhall",
286 => "Energy Transitarium",
289 => "North End",
290 => "Muthru Bazaar",
291 => "East End",
292 => "Southern Plaza",
295 => "Amal's Weaponry",
296 => "Panamis's Protectives",
297 => "Migelo's Sundries",
298 => "Yugri's Magicks",
299 => "Batahn's Technicks",
300 => "Yamoora's Gambits",
301 => "Samalzalam Manor",
302 => "The Clan Hall",
304 => "The Sandsea",
305 => "Eastgate",
306 => "Southgate",
307 => "Westgate",
311 => "Central Spur Stairs",
312 => "East Waterway Control",
313 => "North Spur Sluiceway",
314 => "East Spur Stairs",
315 => "Northern Sluiceway",
316 => "East Waterway Control",
318 => "No. 11 Channel",
319 => "East Sluice Control",
320 => "West Sluice Control",
321 => "No. 10 Channel",
322 => "Central Waterway Control",
326 => "Southern Sluiceway",
329 => "Overflow Cloaca",
332 => "A Vikaari Bhrum",
333 => "Trahk Pis Praa",
334 => "Sthaana Pisces",
335 => "Dha Vikaari Jula",
336 => "Trahk Jilaam Praa'dii",
337 => "Sthaana Aries",
341 => "Crystal Core",
342 => "No. 1 Cloaca",
345 => "Galtea Downs",
346 => "Corridor of Sand",
347 => "Shimmering Horizons",
348 => "The Midfault",
349 => "Windtrace Dunes",
350 => "The Western Divide",
354 => "Wyrm's Nest",
357 => "Shaft Entry",
358 => "Oltam Span",
359 => "Transitway 1",
360 => "Transitway 2",
365 => "Shunia Twinspan",
366 => "Site 2",
367 => "Site 3",
369 => "Tasche Span",
372 => "Site 9",
374 => "Site 11",
376 => "Site 7",
379 => "Platform 1 - East Tanks",
380 => "Platform 1 - Refinery",
381 => "East Junction",
382 => "Primary Tank Complex",
383 => "Central Junction",
384 => "Platform 1 - South Tanks",
385 => "Platform 2 - Refinery",
386 => "Yensa Border Tunnel",
387 => "South Tank Approach",
390 => "The Urutan-Yensa Sea",
391 => "Withering Shores",
392 => "Augur Hill",
393 => "Yellow Sands",
394 => "The Sandscale Bank",
398 => "Demesne of the Sandqueen",
399 => "Trail of Fading Warmth",
400 => "Simoon Bluff",
403 => "Valley of the Dead",
406 => "Hall of the Destroyer",
407 => "Hall of the Sentinel",
410 => "Royal Passage",
411 => "Southfall Passage",
412 => "Northfall Passage",
415 => "Cloister of Flame",
418 => "Chamber of First Light",
421 => "Hall of Effulgent Light",
422 => "Cloister of Distant Song",
426 => "Cloister of the Highborn",
430 => "Hall of the Ivory Covenant",
431 => "Hall of Slumbering Might",
438 => "The Crucible",
441 => "Cloister of Solace",
444 => "Cloister of Reason",
447 => "Paths of Chained Light",
448 => "The Needlebrake",
449 => "Whisperleaf Way",
450 => "The Parting Glade",
453 => "The Rustling Chapel",
456 => "Dell of the Dreamer",
459 => "The Branchway",
460 => "The Greenswathe",
463 => "Fading Vale",
464 => "Head of the Silverflow",
465 => "Freezing Gorge",
468 => "Frozen Brook",
469 => "Icebound Flow",
470 => "Karydine Glacier",
473 => "Path of the Firstfall",
474 => "Spine of the Icewyrm",
475 => "Silverflow's End",
478 => "The Reseta Strand",
479 => "Pora-Pora Sands",
480 => "The Mauleia Strand",
481 => "Cape Uahuk",
482 => "Cape Tialan",
483 => "Kaukula Pass",
484 => "The Hakawea Shore",
488 => "Hunters' Camp",
491 => "Caima Hills",
492 => "The Vaddu Strand",
493 => "Limatra Hills",
494 => "Rava's Pass",
497 => "Old Elanise Road",
498 => "Crossfield",
499 => "The Terraced Bank",
500 => "Journey's Rest",
503 => "North Liavell Hills",
504 => "South Liavell Hills",
505 => "Feddik River",
506 => "The Northsward",
509 => "Footfalls of the Past",
511 => "Echoes from Time's Garden",
517 => "City of Other Days",
518 => "Path of Hidden Blessing",
522 => "They Who Thirst Not",
525 => "Field of Fallen Wings",
526 => "The Switchback",
527 => "Haulo Green",
530 => "Dagan Flats",
531 => "Field of Light Winds",
532 => "The Greensnake",
533 => "Sunlit Path",
536 => "The Shred",
539 => "Walk of Flitting Rifts",
540 => "Walk of Stolen Truths",
541 => "Walk of Dancing Shadow",
542 => "Antiquity's End",
545 => "Redolent Glade",
548 => "White Magick's Embrace",
549 => "Ice Field of Clearsight",
550 => "The Edge of Reason",
552 => "Port Launch",
555 => "Port Section",
556 => "Large Freight Stores",
557 => "Starboard Section",
558 => "Sub-control Room",
561 => "Airship Berth Access",
564 => "Central Brig Access",
567 => "Cellar Stores",
568 => "Cellars",
569 => "Lower Halls",
570 => "Secret Passage",
571 => "Treasure Room No. 8",
572 => "The Garden Stairs",
576 => "Invitation to Heresy",
577 => "Sandfalls",
578 => "Hourglass Basin",
581 => "The Undershore",
582 => "Halls of Ardent Darkness",
585 => "The Balamka Fault",
586 => "Drybeam Cavern",
587 => "Darkened Wharf",
588 => "Canopy of Clay",
590 => "Athroza Quicksands",
593 => "Walk of Sky",
594 => "Walk of Mind",
597 => "Ward of Measure",
598 => "Cold Distance",
599 => "Walk of Prescience",
600 => "Walk of Reason",
603 => "Ward of Steel",
606 => "Ward of Velitation",
607 => "Walk of Torn Illusion",
608 => "Walk of Revelation",
609 => "Ward of the Sword-King",
612 => "Hall of Worth",
615 => "Vault of the Champion",
618 => "Throne of Veiled Gods",
621 => "A Prama Vikaari",
622 => "Kabonii Jilaam Pratii'vaa",
623 => "Kabonii Jilaam Avaa",
624 => "Dha Vikaari Bhrum",
625 => "Sthaana Scorpio",
626 => "A Vikaari Dhebon",
630 => "West Barbican",
631 => "Jajim Bazaar",
632 => "West Ward",
635 => "Grand Arcade",
636 => "Highgarden Terrace",
640 => "Molberry",
641 => "Trant",
642 => "Charlotte's Magickery",
643 => "Bulward's Technicks",
666 => "Womb of the Sun-cryst",
668 => "Womb of the Sun-cryst",
670 => "Heaven's Challenge",
682 => "Hell's Challenge",
686 => "Gate of Earth",
687 => "Gate of Water",
690 => "The Trimahla Water-Steps",
691 => "The Aadha Water-Steps",
694 => "The Haalmikah Water-Steps",
695 => "Gate of Fire",
698 => "Gate of Wind",
701 => "North Sprawl",
702 => "South Sprawl",
703 => "Dalan's House",
704 => "Residence",
709 => "The Black Watch",
710 => "The Confiscatory",
712 => "North Entrance",
713 => "Pithead Junction A",
714 => "Phase 1 Shaft",
715 => "Phase 1 Dig",
716 => "Crossover A",
717 => "Pithead Junction B",
718 => "Staging Shaft",
719 => "Crossover B",
722 => "Ore Separation",
725 => "Phase 2 Dig",
726 => "Crossover C",
727 => "Pithead Junction C",
728 => "Phase 2 Shaft",
730 => "Special Charter Shaft",
733 => "Special Charter Dig",
736 => "Hall of the Light",
737 => "Hall of the Light",
738 => "Temple Grounds",
741 => "Temple Approach",
742 => "Sand-strewn Pass",
745 => "Nilbasse",
746 => "Rienna",
747 => "Vint's Armaments",
748 => "Granch's Requisites",
749 => "Lebleu's Gambits",
751 => "Banks of the Sogoht",
752 => "Lull of the Land",
753 => "The Elderknoll",
756 => "Tsenoble",
762 => "Alley of Muted Sighs",
763 => "Alley of Low Whispers",
766 => "Fane of the Path",
767 => "The Spiritwood",
768 => "Road of Verdant Praise",
774 => "Periphery",
775 => "Catwalk",
776 => "Antechamber",
777 => "Antechamber",
779 => "Central Lift",
782 => "Central Shaft",
785 => "Cannon Superstructure",
788 => "Aerodrome (Rabanastre)",
791 => "Aerodrome (Bhujerba)",
794 => "Aerodrome (Archades)",
797 => "Aerodrome (Balfonheim Port)",
800 => "Aerodrome (Nalbina Town)",
803 => "Travica Way",
804 => "Cloudborne Row",
805 => "Miners' End",
806 => "Lhusu Square",
809 => "Khus Skygrounds",
810 => "Kaff Terrace",
813 => "Targe's Arms",
814 => "Rithil's Protectives",
816 => "Mait's Magicks",
817 => "Clio's Technicks",
818 => "Bashketi's Gambits",
819 => "The Staras Residence",
820 => "The Cloudborne",
823 => "Sea Breeze Lane",
824 => "Gallerina Marketplace",
825 => "Quayside Court",
826 => "Saccio Lane",
827 => "Chivany Breakwater",
828 => "Canal Lane",
833 => "Beruny's Armaments",
834 => "Odo's Technicks",
835 => "Port Villa",
836 => "The Whitecap",
837 => "Port Villa",
838 => "No. 11 Channel",
839 => "No. 11 Channel",
840 => "East Sluice Control",
841 => "Southern Sluiceway",
842 => "West Sluice Control",
843 => "No. 10 Channel",
844 => "No. 10 Channel",
845 => "No. 3 Cloaca Spur",
846 => "No. 3 Cloaca Spur",
847 => "No. 1 Cloaca",
848 => "No. 4 Cloaca Spur",
849 => "No. 4 Cloaca Spur",
850 => "Central Waterway Control",
854 => "C.D.B.",
856 => "Dalan's Marker",
871 => "Bridge",
872 => "Battle Launch",
876 => "Brig No. 1",
888 => "Crystal Peak",
891 => "East-West Bypass",
892 => "The Zeviah Span",
893 => "West Annex",
894 => "Terminus No. 7 Adjunct",
895 => "Special Op Sector 5",
898 => "Colosseum",
901 => "Lasche Span",
902 => "Site 5",
903 => "Site 6 South",
904 => "Site 6 North",
905 => "Staging Area",
908 => "Living Chasm",
916 => "Siti Bhrusuna",
926 => "A Vikaari Kabonii",
927 => "Sthaana Cancer",
928 => "Bhrum Pis Avaa",
929 => "Bhrum Pis Pratii",
930 => "Dha Vikaari Trahk",
933 => "Site 2",
934 => "Shunia Twinspan",
935 => "Transitway 1",
936 => "Oltam Span",
939 => "Dha Vikaari Kabonii",
940 => "A Vikaari Kanbhru Ra",
941 => "Dhebon Jilaam Praa'dii",
942 => "Dhebon Jilaam Pratii'dii",
943 => "Sthaana Sagittarius",
944 => "A Vikaari Sirhru Pratii",
945 => "A Vikaari Sirhru Praa",
946 => "Dhebon Jilaam Avaapratii",
947 => "A Vikaari Sirhru Si",
949 => "Dhebon Jilaam Avaa",
952 => "Dha Vikaari Dhebon Praa",
953 => "Dha Vikaari Dhebon Pratii",
954 => "Sirhru Phullam Praa",
955 => "Sthaana Leo",
956 => "Sirhru Phullam Praa'vaa",
957 => "Sirhru Phullam Pratii'vaa",
958 => "Sthaana Gemini",
959 => "Sirhru Phullam Udiipratii",
960 => "Sirhru Jilaam Praa'dii",
961 => "Sirhru Jilaam Pratii'dii",
962 => "Sirhru Jilaam Praa",
963 => "Sirhru Jilaam Pratii",
964 => "Sirhru Jilaam Praa'vaa",
965 => "Sirhru Jilaam Pratii'vaa",
966 => "Sirhru Pis Praa",
967 => "Sirhru Pis Pratii",
968 => "Sirhru Pis Avaa",
969 => "Sirhru Jilaam Avaapratii",
970 => "Sirhru Jilaam Avaapraa",
971 => "A Vikaari Uldobi",
972 => "A Vikaari Uldobi Si",
973 => "Dha Vikaari Dhebon Si",
979 => "Dha Vikaari Sirhru",
980 => "Sthaana Virgo",
981 => "Uldobi Jilaam Praa'dii",
982 => "Uldobi Jilaam Pratii",
983 => "Uldobi Jilaam Praa",
984 => "Uldobi Phullam Pratii'dii",
985 => "Sthaana Capricorn",
986 => "Dha Vikaari Sirhru Si",
987 => "Uldobi Phullam Udiipraa",
988 => "Uldobi Phullam Pratii'vaa",
989 => "Uldobi Phullam Praa'vaa",
990 => "Uldobi Phullam Pratii",
991 => "Sthaana Taurus",
992 => "Sthaana Libra",
993 => "Uldobi Jilaam Praa'vaa",
994 => "Uldobi Jilaam Pratii'vaa",
995 => "Uldobi Jilaam Avaa",
996 => "A Vikaari Kanbhru",
1002 => "Dha Vikaari Uldobi",
1003 => "Kanbhru Pis",
1004 => "Dha Vikaari Dhebon Ra",
1005 => "Sthaana Aquarius",
1008 => "66th Floor",
1009 => "Rm 6613 West",
1010 => "Rm 6613 East",
1011 => "Rm 6612 West",
1013 => "Rm 6611 West",
1014 => "Rm 6611 East",
1015 => "Rm 6602 West",
1016 => "Rm 6601 West",
1017 => "Rm 6602 East",
1018 => "Rm 6601 East",
1019 => "67th Floor",
1020 => "Rm 6711 West",
1021 => "Rm 6711 East",
1023 => "Rm 6703 West",
1024 => "Rm 6704 East",
1025 => "Rm 6703 East",
1026 => "Rm 6702 West",
1027 => "Rm 6701 West",
1028 => "Rm 6702 East",
1030 => "68th Floor",
1031 => "69th Floor",
1036 => "66th Floor",
1037 => "Rm 6613 West",
1038 => "Rm 6613 East",
1039 => "Rm 6612 West",
1041 => "Rm 6611 West",
1042 => "Rm 6611 East",
1043 => "Rm 6602 West",
1044 => "Rm 6601 West",
1045 => "Rm 6602 East",
1046 => "Rm 6601 East",
1047 => "70th Floor",
1048 => "Rm 7002 West",
1049 => "Rm 7001 West",
1050 => "Rm 7002 East",
1054 => "67th Floor",
1055 => "Rm 6711 West",
1056 => "Rm 6711 East",
1058 => "Rm 6703 West",
1059 => "Rm 6704 East",
1060 => "Rm 6703 East",
1061 => "Rm 6702 West",
1062 => "Rm 6701 West",
1063 => "Rm 6702 East",
1067 => "68th Floor",
1068 => "Rm 6814 West",
1069 => "Rm 6814 East",
1070 => "Rm 6813 West",
1071 => "Rm 6813 East",
1072 => "Rm 6812 West",
1073 => "Rm 6812 East",
1074 => "Rm 6811 West",
1075 => "Rm 6811 East",
1076 => "Rm 6804 West",
1077 => "Rm 6803 West",
1078 => "Rm 6804 East",
1079 => "Rm 6803 East",
1080 => "Rm 6802 West",
1081 => "Rm 6801 West",
1082 => "Rm 6802 East",
1083 => "Rm 6801 East",
1088 => "Rm 6912 East",
1089 => "Rm 6911 West",
1091 => "Rm 6904 West",
1094 => "Rm 6903 East",
1095 => "Rm 6902 West",
1096 => "Rm 6901 West",
1098 => "Rm 6901 East",
1101 => "The Wellspring",
1102 => "Horizon's Break",
1103 => "The Reach",
1104 => "Reach of the Damned",
1105 => "Reach of the Occult",
1111 => "Wellspring Labyrinth",
1113 => "Dunes of Profaning Wind",
1114 => "Blackrock Vault",
1115 => "Wellspring Ravel - 1st Flight",
1116 => "Wellspring Ravel - 2nd Flight",
1118 => "Wellspring Ravel - 3rd Flight",
1119 => "Wellspring Ravel - 4th Flight",
1121 => "Marsh of Profaning Wind",
1122 => "Horizon's Cusp",
1123 => "Penumbra - Interior",
1124 => "Penumbra - North",
1125 => "Penumbra - South",
1126 => "Umbra - Interior",
1127 => "Umbra - North",
1128 => "Umbra - South",
1129 => "Abyssal - Interior",
1130 => "Abyssal - North",
1131 => "Abyssal - South",
1132 => "Cleft of Profaning Wind",
1133 => "The Bounds of Truth",
1134 => "Station of Banishment",
1136 => "Station of Suffering",
1138 => "Station of Ascension",
1140 => "Spire Ravel - 1st Flight",
1141 => "Spire Ravel - 2nd Flight",
1143 => "Empyrean Ravel",
1145 => "Overflow Cloaca",
1150 => "Air Deck",
1151 => "Babbling Vale",
1153 => "Withering Shores",
1155 => "Stage 1",
1156 => "Stage 2",
1157 => "Stage 3",
1158 => "Stage 4",
1159 => "Stage 5",
1163 => "Stage 6",
1164 => "Stage 7",
1165 => "Stage 8",
1166 => "Stage 9",
1167 => "Stage 10",
1171 => "Stage 11",
1172 => "Stage 12",
1173 => "Stage 13",
1174 => "Stage 14",
1175 => "Stage 15",
1179 => "Stage 16",
1180 => "Stage 17",
1181 => "Stage 18",
1182 => "Stage 19",
1183 => "Stage 20",
1187 => "Stage 21",
1188 => "Stage 22",
1189 => "Stage 23",
1190 => "Stage 24",
1191 => "Stage 25",
1195 => "Stage 26",
1196 => "Stage 27",
1197 => "Stage 28",
1198 => "Stage 29",
1199 => "Stage 30",
1203 => "Stage 31",
1204 => "Stage 32",
1205 => "Stage 33",
1206 => "Stage 34",
1207 => "Stage 35",
1211 => "Stage 36",
1212 => "Stage 37",
1213 => "Stage 38",
1214 => "Stage 39",
1215 => "Stage 40",
1219 => "Stage 41",
1220 => "Stage 42",
1221 => "Stage 43",
1222 => "Stage 44",
1223 => "Stage 45",
1227 => "Stage 46",
1228 => "Stage 47",
1229 => "Stage 48",
1230 => "Stage 49",
1231 => "Stage 50",
1235 => "Stage 51",
1236 => "Stage 52",
1237 => "Stage 53",
1238 => "Stage 54",
1239 => "Stage 55",
1243 => "Stage 56",
1244 => "Stage 57",
1245 => "Stage 58",
1246 => "Stage 59",
1247 => "Stage 60",
1251 => "Stage 61",
1252 => "Stage 62",
1253 => "Stage 63",
1254 => "Stage 64",
1255 => "Stage 65",
1259 => "Stage 66",
1260 => "Stage 67",
1261 => "Stage 68",
1262 => "Stage 69",
1263 => "Stage 70",
1267 => "Stage 71",
1268 => "Stage 72",
1269 => "Stage 73",
1270 => "Stage 74",
1271 => "Stage 75",
1275 => "Stage 76",
1276 => "Stage 77",
1277 => "Stage 78",
1278 => "Stage 79",
1279 => "Stage 80",
1283 => "Stage 81",
1284 => "Stage 82",
1285 => "Stage 83",
1286 => "Stage 84",
1287 => "Stage 85",
1291 => "Stage 86",
1292 => "Stage 87",
1293 => "Stage 88",
1294 => "Stage 89",
1295 => "Stage 90",
1299 => "Stage 91",
1300 => "Stage 92",
1301 => "Stage 93",
1302 => "Stage 94",
1303 => "Stage 95",
1307 => "Stage 96",
1308 => "Stage 97",
1309 => "Stage 98",
1310 => "Stage 99",
1311 => "Stage 100",
};
}