diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4873580..709ca61 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,9 @@ name: CI on: push: - branches: [main] + branches: [dev, prod] pull_request: + branches: [dev, prod] workflow_call: permissions: @@ -30,7 +31,7 @@ jobs: os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: Swatinem/rust-cache@v2 - name: cargo test run: cargo test --locked @@ -47,7 +48,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: Swatinem/rust-cache@v2 - name: cargo fmt run: cargo fmt --all --check @@ -57,9 +58,9 @@ jobs: extension: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: Swatinem/rust-cache@v2 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: 22 cache: npm diff --git a/.github/workflows/corpus.yml b/.github/workflows/corpus.yml index 74b4c5a..9e5bb31 100644 --- a/.github/workflows/corpus.yml +++ b/.github/workflows/corpus.yml @@ -19,7 +19,7 @@ jobs: corpus: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - uses: Swatinem/rust-cache@v2 - name: Fetch corpus run: bash scripts/fetch-corpus.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fbcded9..5629bb6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,67 +1,119 @@ -# Tag-triggered release pipeline. -# -# Push a tag `vX.Y.Z` (matching the workspace version in Cargo.toml) and this -# workflow builds the server for Windows x64 and Linux x64 (musl-static), -# packages platform-specific VS Code extensions with the binary bundled, -# publishes a GitHub Release with SHA-256 checksums, and — when VSCE_PAT is -# configured as a repository secret — publishes the extension to the VS Code -# Marketplace (skipped, not failed, when the token is absent). -# -# See docs/release.md for the step-by-step release procedure. +# Manual release pipeline for both GitHub pre-releases and live releases. name: Release on: - push: - tags: ["v*"] + workflow_dispatch: + inputs: + release_type: + description: Release type + required: true + default: prerelease + type: choice + options: + - prerelease + - release permissions: contents: write + pull-requests: write + +concurrency: + group: release + cancel-in-progress: false env: BIN_NAME: zerosyntax-lsp CARGO_TERM_COLOR: always jobs: - ci: - uses: ./.github/workflows/ci.yml - - corpus: - uses: ./.github/workflows/corpus.yml - - # The tag is the single source of truth for the release version; it must - # match the Rust workspace version so the binary's provenance is unambiguous. - # (The extension version is stamped from the tag at package time.) - check-version: - needs: [ci, corpus] + prepare: runs-on: ubuntu-latest + outputs: + dev_sha: ${{ steps.release.outputs.dev_sha }} + tag: ${{ steps.release.outputs.tag }} + version: ${{ steps.release.outputs.version }} steps: - - uses: actions/checkout@v4 - - name: Tag matches workspace version + - uses: actions/checkout@v7 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + - name: Resolve and validate release + id: release + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TYPE: ${{ inputs.release_type }} run: | - tag="${GITHUB_REF_NAME#v}" - crate="$(cargo metadata --locked --no-deps --format-version 1 \ + if [ "$GITHUB_REF" != "refs/heads/dev" ]; then + echo "::error::run the release workflow from the dev branch" >&2 + exit 1 + fi + + version="$(cargo metadata --locked --no-deps --format-version 1 \ | jq -r '.packages[] | select(.name == "zerosyntax-server") | .version')" - if [ "$tag" != "$crate" ]; then - echo "::error::tag v$tag does not match workspace version $crate" >&2 + if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Cargo workspace version must be a major.minor.patch release version, got '$version'" >&2 + exit 1 + fi + + dev_sha="$(git rev-parse HEAD)" + stable_tag="v$version" + if [ "$RELEASE_TYPE" = "prerelease" ]; then + tag="$stable_tag-pre.$GITHUB_RUN_NUMBER" + if git ls-remote --exit-code --tags origin "refs/tags/$stable_tag" >/dev/null 2>&1 \ + || gh release view "$stable_tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + echo "::error::$stable_tag is already released; bump the Cargo workspace version" >&2 + exit 1 + fi + else + tag="$stable_tag" + git fetch origin prod:refs/remotes/origin/prod + base="$(git merge-base origin/prod "$dev_sha")" + if ! git diff --quiet "$base" origin/prod; then + echo "::error::prod has content changes not present in dev; merge prod into dev first" >&2 + exit 1 + fi + if git diff --quiet origin/prod "$dev_sha"; then + echo "::error::dev has no changes to release" >&2 + exit 1 + fi + fi + + if git ls-remote --exit-code --tags origin "refs/tags/$tag" >/dev/null 2>&1 \ + || gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + echo "::error::$tag already exists" >&2 exit 1 fi + echo "dev_sha=$dev_sha" >> "$GITHUB_OUTPUT" + echo "tag=$tag" >> "$GITHUB_OUTPUT" + echo "version=$version" >> "$GITHUB_OUTPUT" + + ci: + needs: prepare + uses: ./.github/workflows/ci.yml + + corpus: + needs: prepare + uses: ./.github/workflows/corpus.yml + build: - needs: check-version + needs: [prepare, ci, corpus] strategy: fail-fast: false matrix: include: - target: x86_64-pc-windows-msvc os: windows-latest - # musl => fully static binary, runs on any x64 Linux regardless of - # glibc version (all dependencies are pure Rust). - target: x86_64-unknown-linux-musl os: ubuntu-latest runs-on: ${{ matrix.os }} + env: + RELEASE_TAG: ${{ needs.prepare.outputs.tag }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 + with: + ref: ${{ needs.prepare.outputs.dev_sha }} - name: Install musl linker if: matrix.target == 'x86_64-unknown-linux-musl' run: sudo apt-get update && sudo apt-get install -y musl-tools @@ -69,16 +121,13 @@ jobs: run: rustup target add ${{ matrix.target }} - uses: Swatinem/rust-cache@v2 with: - key: ${{ matrix.target }} + key: release-${{ matrix.target }} - name: Build run: cargo build --locked --release -p zerosyntax-server --target ${{ matrix.target }} - - # Archive on the build machine so the Unix executable bit survives - # (upload-artifact does not preserve file permissions). - name: Package (unix) if: runner.os != 'Windows' run: | - staging="${BIN_NAME}-${GITHUB_REF_NAME}-${{ matrix.target }}" + staging="${BIN_NAME}-${RELEASE_TAG}-${{ matrix.target }}" mkdir "$staging" bin cp "target/${{ matrix.target }}/release/${BIN_NAME}" bin/ cp "target/${{ matrix.target }}/release/${BIN_NAME}" "$staging/" @@ -90,7 +139,7 @@ jobs: if: runner.os == 'Windows' shell: pwsh run: | - $staging = "$env:BIN_NAME-$env:GITHUB_REF_NAME-${{ matrix.target }}" + $staging = "$env:BIN_NAME-$env:RELEASE_TAG-${{ matrix.target }}" New-Item -ItemType Directory -Path $staging | Out-Null New-Item -ItemType Directory -Path bin | Out-Null Copy-Item "target/${{ matrix.target }}/release/$env:BIN_NAME.exe" bin @@ -100,9 +149,7 @@ jobs: Compress-Archive -Path $staging -DestinationPath "$staging.zip" (Get-FileHash "$staging.zip" -Algorithm SHA256).Hash.ToLower() + " $staging.zip" ` | Out-File -Encoding ascii "$staging.zip.sha256" - - - name: Upload release archive - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: dist-${{ matrix.target }} path: | @@ -111,21 +158,14 @@ jobs: *.zip *.zip.sha256 if-no-files-found: error - # Raw binary for the vsix job (which re-sets the exec bit itself). The - # bin/ staging dir holds exactly the binary — a target-dir glob would - # also catch .d/.pdb build by-products. - - name: Upload raw binary - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: bin-${{ matrix.target }} path: bin/* if-no-files-found: error - # One .vsix per platform, each with that platform's server binary bundled - # under the extension's server/ directory (`vsce package --target`). The - # extension still honors the `zerosyntax.server.path` override. vsix: - needs: build + needs: [prepare, build] runs-on: ubuntu-latest strategy: fail-fast: false @@ -136,44 +176,57 @@ jobs: - vsce-target: linux-x64 rust-target: x86_64-unknown-linux-musl steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v7 + with: + ref: ${{ needs.prepare.outputs.dev_sha }} + - uses: actions/setup-node@v6 with: node-version: 22 cache: npm cache-dependency-path: editors/vscode/package-lock.json - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: name: bin-${{ matrix.rust-target }} path: editors/vscode/server - name: Package extension working-directory: editors/vscode + env: + RELEASE_TAG: ${{ needs.prepare.outputs.tag }} + RELEASE_TYPE: ${{ inputs.release_type }} + VERSION: ${{ needs.prepare.outputs.version }} run: | chmod +x server/${BIN_NAME}* || true [ -f ../../LICENSE ] && cp ../../LICENSE . npm ci - # Stamp the extension with the release version (tag is authoritative). - npm version "${GITHUB_REF_NAME#v}" --no-git-tag-version --allow-same-version - npx --yes @vscode/vsce package --target ${{ matrix.vsce-target }} \ - -o "zerosyntax-vscode-${{ matrix.vsce-target }}-${GITHUB_REF_NAME#v}.vsix" - - uses: actions/upload-artifact@v4 + npm version "$VERSION" --no-git-tag-version --allow-same-version + args=() + if [ "$RELEASE_TYPE" = "prerelease" ]; then args+=(--pre-release); fi + npx --yes @vscode/vsce package "${args[@]}" --target ${{ matrix.vsce-target }} \ + -o "zerosyntax-vscode-${{ matrix.vsce-target }}-${RELEASE_TAG#v}.vsix" + - uses: actions/upload-artifact@v7 with: name: vsix-${{ matrix.vsce-target }} path: editors/vscode/*.vsix if-no-files-found: error - release: - needs: [build, vsix] + publish-release: + needs: [prepare, build, vsix] runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ needs.prepare.outputs.tag }} + RELEASE_TYPE: ${{ inputs.release_type }} steps: - # Only dist-* and vsix-* — merging bin-* would collide the - # identically-named raw binaries from different targets. - - uses: actions/download-artifact@v4 + - uses: actions/checkout@v7 + with: + ref: ${{ needs.prepare.outputs.dev_sha }} + fetch-depth: 0 + - uses: actions/download-artifact@v8 with: pattern: dist-* path: dist merge-multiple: true - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 with: pattern: vsix-* path: dist @@ -182,20 +235,57 @@ jobs: run: | cd dist sha256sum *.tar.gz *.zip *.vsix > SHA256SUMS.txt - - name: Create GitHub Release - env: - GH_TOKEN: ${{ github.token }} + - name: Merge production release + id: target run: | - gh release create "$GITHUB_REF_NAME" dist/* \ - --repo "$GITHUB_REPOSITORY" \ - --title "$GITHUB_REF_NAME" \ + dev_sha="${{ needs.prepare.outputs.dev_sha }}" + if [ "$RELEASE_TYPE" = "release" ]; then + pr_url="$(gh pr create \ + --repo "$GITHUB_REPOSITORY" \ + --base prod \ + --head dev \ + --title "Release $RELEASE_TAG" \ + --body "Automated production release for $RELEASE_TAG.")" + gh pr merge "$pr_url" \ + --repo "$GITHUB_REPOSITORY" \ + --merge \ + --match-head-commit "$dev_sha" + target_sha="$(gh pr view "$pr_url" --repo "$GITHUB_REPOSITORY" \ + --json mergeCommit --jq '.mergeCommit.oid')" + if [ -z "$target_sha" ] || [ "$target_sha" = "null" ]; then + echo "::error::could not resolve the prod merge commit" >&2 + exit 1 + fi + else + target_sha="$dev_sha" + fi + echo "sha=$target_sha" >> "$GITHUB_OUTPUT" + - name: Create tag and GitHub Release + run: | + target_sha="${{ steps.target.outputs.sha }}" + gh api "repos/$GITHUB_REPOSITORY/git/refs" --method POST \ + -f ref="refs/tags/$RELEASE_TAG" -f sha="$target_sha" + + previous_stable="$(gh api "repos/$GITHUB_REPOSITORY/releases?per_page=100" \ + --jq 'map(select(.draft == false and .prerelease == false))[0].tag_name // ""')" + args=( + --repo "$GITHUB_REPOSITORY" + --title "$RELEASE_TAG" + --target "$target_sha" + --verify-tag --generate-notes + ) + if [ -n "$previous_stable" ]; then args+=(--notes-start-tag "$previous_stable"); fi + if [ "$RELEASE_TYPE" = "prerelease" ]; then + args+=(--prerelease --latest=false) + else + args+=(--latest) + fi + gh release create "$RELEASE_TAG" dist/* "${args[@]}" - # Publishing requires the VSCE_PAT secret configured in the repository; - # the job is skipped (not failed) when the token is absent, so the GitHub - # Release itself never depends on marketplace credentials. publish-marketplace: - needs: release + needs: publish-release + if: inputs.release_type == 'release' runs-on: ubuntu-latest env: VSCE_PAT: ${{ secrets.VSCE_PAT }} @@ -204,9 +294,9 @@ jobs: id: token run: | if [ -n "$VSCE_PAT" ]; then echo "present=true" >> "$GITHUB_OUTPUT"; fi - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 if: steps.token.outputs.present == 'true' - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 if: steps.token.outputs.present == 'true' with: node-version: 22 @@ -216,7 +306,7 @@ jobs: if: steps.token.outputs.present == 'true' working-directory: editors/vscode run: npm ci - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8 if: steps.token.outputs.present == 'true' with: pattern: vsix-* diff --git a/Cargo.lock b/Cargo.lock index 28aab91..cd1151e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + [[package]] name = "anes" version = "0.1.6" @@ -57,12 +66,6 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" - [[package]] name = "bitflags" version = "1.3.2" @@ -93,6 +96,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "cc" +version = "1.2.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -159,25 +172,24 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" [[package]] name = "criterion" -version = "0.5.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" dependencies = [ + "alloca", "anes", "cast", "ciborium", "clap", "criterion-plot", - "is-terminal", "itertools", "num-traits", - "once_cell", "oorandom", + "page_size", "plotters", "rayon", "regex", "serde", - "serde_derive", "serde_json", "tinytemplate", "walkdir", @@ -185,9 +197,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.5.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" dependencies = [ "cast", "itertools", @@ -284,6 +296,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "fnv" version = "1.0.7" @@ -398,12 +416,6 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - [[package]] name = "httparse" version = "1.10.1" @@ -523,22 +535,11 @@ dependencies = [ "hashbrown 0.17.1", ] -[[package]] -name = "is-terminal" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - [[package]] name = "itertools" -version = "0.10.5" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -595,34 +596,32 @@ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "logos" -version = "0.15.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154" +checksum = "eb2c55a318a87600ea870ff8c2012148b44bf18b74fad48d0f835c38c7d07c5f" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.15.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "192a3a2b90b0c05b27a0b2c43eecdb7c415e29243acc3f89cc8247a5b693045c" +checksum = "58b3ffaa284e1350d017a57d04ada118c4583cf260c8fb01e0fe28a2e9cf8970" dependencies = [ - "beef", "fnv", - "lazy_static", "proc-macro2", "quote", + "regex-automata", "regex-syntax", - "rustc_version", "syn", ] [[package]] name = "logos-derive" -version = "0.15.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470" +checksum = "52d3a9855747c17eaf4383823f135220716ab49bea5fbea7dd42cc9a92f8aa31" dependencies = [ "logos-codegen", ] @@ -696,6 +695,16 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "parking_lot" version = "0.12.5" @@ -892,15 +901,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - [[package]] name = "rustversion" version = "1.0.22" @@ -922,12 +922,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - [[package]] name = "serde" version = "1.0.228" @@ -984,11 +978,11 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -1000,6 +994,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -1144,44 +1144,42 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "serde", + "indexmap", + "serde_core", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ - "serde", + "serde_core", ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "toml_parser" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", "winnow", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_writer" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tower" @@ -1406,6 +1404,22 @@ dependencies = [ "wasm-bindgen", ] +[[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-util" version = "0.1.11" @@ -1415,6 +1429,12 @@ dependencies = [ "windows-sys", ] +[[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 = "windows-link" version = "0.2.1" @@ -1432,12 +1452,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.15" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" [[package]] name = "writeable" @@ -1511,7 +1528,7 @@ dependencies = [ [[package]] name = "zerosyntax-analysis" -version = "1.0.3" +version = "1.0.5" dependencies = [ "criterion", "rowan", @@ -1523,7 +1540,7 @@ dependencies = [ [[package]] name = "zerosyntax-schema" -version = "1.0.3" +version = "1.0.5" dependencies = [ "serde", "serde_json", @@ -1531,7 +1548,7 @@ dependencies = [ [[package]] name = "zerosyntax-server" -version = "1.0.3" +version = "1.0.5" dependencies = [ "anyhow", "dashmap 6.2.1", @@ -1550,7 +1567,7 @@ dependencies = [ [[package]] name = "zerosyntax-syntax" -version = "1.0.3" +version = "1.0.5" dependencies = [ "criterion", "logos", diff --git a/Cargo.toml b/Cargo.toml index 6ed234d..236dcf6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/schema", "crates/syntax", "crates/analysis", "crates/server"] [workspace.package] -version = "1.0.3" +version = "1.0.5" edition = "2021" license = "MIT" repository = "https://github.com/ViTeXFTW/ZeroSyntaxV2" @@ -16,14 +16,14 @@ zerosyntax-analysis = { path = "crates/analysis" } serde = { version = "1", features = ["derive"] } serde_json = "1" -toml = "0.8" +toml = "1.1" anyhow = "1" thiserror = "2" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # syntax -logos = "0.15" +logos = "0.16" rowan = "0.16" # server @@ -36,4 +36,4 @@ dashmap = "6" walkdir = "2" # benches -criterion = "0.5" +criterion = "0.8" diff --git a/README.md b/README.md index a41fc44..f44042e 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,10 @@ and starts the bundled language server automatically. Formatting is off by default. Enable it with `zerosyntax.format.enable` when you want the server to advertise document formatting to VS Code. -For map/solo.ini diagnostics, set `zerosyntax.baseIniRoots` to game or mod INI -directories and/or `.big` archives. Those definitions are treated as already -loaded before the map file. +For map/solo.ini diagnostics and W3D model/bone completions, set +`zerosyntax.baseIniRoots` to game or mod directories and/or `.big` archives. +INI definitions are treated as already loaded before the map file; W3D assets +are indexed for model and bone checks. ### Standalone language server diff --git a/crates/analysis/src/actions.rs b/crates/analysis/src/actions.rs index 22ee1b1..ff19023 100644 --- a/crates/analysis/src/actions.rs +++ b/crates/analysis/src/actions.rs @@ -207,8 +207,8 @@ fn diagnostic_fixes( } } -/// For an `unreachable-set` diagnostic offer (a) remove the dead sub-block -/// and (b) insert the trigger module before the enclosing Object's `End`. +/// For an `unreachable-set` diagnostic offer the mechanical counterpart: +/// remove/scaffold for dead sets, or add the missing set for a useless upgrade. fn unreachable_set_fixes( parse: &Parse, text: &str, @@ -231,6 +231,9 @@ fn unreachable_set_fixes( .and_then(|n| n.parent()) .filter(|n| n.kind() == SyntaxKind::MODULE); let Some(set_module_node) = set_module_node else { + if tok.text().eq_ignore_ascii_case("WeaponSetUpgrade") { + unused_weapon_set_upgrade_fix(text, &tok, scaffold_seen, out); + } return; }; @@ -286,13 +289,7 @@ fn unreachable_set_fixes( let insert_at = find_end_line_start(&object_node, text) .unwrap_or_else(|| u32::from(object_node.text_range().end())); - // Indent: the set module starts at its own leading whitespace. - let module_start = u32::from(set_module_node.text_range().start()) as usize; - let indent_len = text[module_start..] - .bytes() - .take_while(|&b| b == b' ' || b == b'\t') - .count(); - let indent = &text[module_start..module_start + indent_len]; + let indent = leading_indent(&set_module_node, text); let body_indent = format!("{indent} "); out.push(Fix { @@ -304,6 +301,47 @@ fn unreachable_set_fixes( }); } +fn unused_weapon_set_upgrade_fix( + text: &str, + tok: &SyntaxToken, + scaffold_seen: &mut std::collections::HashSet<(u32, &'static str)>, + out: &mut Vec, +) { + let Some(module_node) = tok.parent().filter(|n| n.kind() == SyntaxKind::MODULE) else { + return; + }; + let Some(object_node) = module_node + .ancestors() + .find(|n| n.kind() == SyntaxKind::BLOCK) + else { + return; + }; + let block_start = u32::from(object_node.text_range().start()); + if !scaffold_seen.insert((block_start, "WeaponSet")) { + return; + } + + let insert_at = u32::from(module_node.text_range().start()); + let indent = leading_indent(&module_node, text); + let body_indent = format!("{indent} "); + out.push(Fix { + title: "Insert `PLAYER_UPGRADE` WeaponSet".to_string(), + span: Span::new(insert_at, insert_at), + new_text: format!( + "{indent}WeaponSet\n{body_indent}Conditions = PLAYER_UPGRADE\n{body_indent}Weapon = PRIMARY NONE\n{indent}End\n" + ), + }); +} + +fn leading_indent<'a>(node: &SyntaxNode, text: &'a str) -> &'a str { + let start = u32::from(node.text_range().start()) as usize; + let indent_len = text[start..] + .bytes() + .take_while(|&b| b == b' ' || b == b'\t') + .count(); + &text[start..start + indent_len] +} + /// Return the byte offset of the start of the `End` line within `block`. fn find_end_line_start(block: &SyntaxNode, text: &str) -> Option { // children_with_tokens() is not DoubleEndedIterator; collect to reverse. @@ -594,6 +632,37 @@ mod tests { ); } + #[test] + fn unused_weapon_set_upgrade_offers_player_upgrade_weapon_set() { + let src = concat!( + "Object Tank\n", + " WeaponSet\n", + " Conditions = NONE\n", + " Weapon = PRIMARY MyGun\n", + " End\n", + " Behavior = WeaponSetUpgrade ModuleTag_01\n", + " TriggeredBy = Upgrade_MyGun\n", + " End\n", + "End\n", + "Weapon MyGun\n", + " PrimaryDamage = 10.0\n", + "End\n", + ); + let fx = all_fixes(src); + let insert = fx + .iter() + .find(|f| f.title.contains("PLAYER_UPGRADE") && f.title.contains("WeaponSet")) + .expect("missing WeaponSet scaffold fix"); + let mut result = src.to_string(); + result.replace_range( + insert.span.start as usize..insert.span.end as usize, + &insert.new_text, + ); + assert!(result.contains( + " WeaponSet\n Conditions = PLAYER_UPGRADE\n Weapon = PRIMARY NONE\n End\n Behavior = WeaponSetUpgrade" + )); + } + #[test] fn unreachable_set_tag_skips_collisions() { // Object already has ModuleTag_01 and MODULETAG_02 (case variant) → should generate ModuleTag_03. diff --git a/crates/analysis/src/completion.rs b/crates/analysis/src/completion.rs index 0018889..3e03b78 100644 --- a/crates/analysis/src/completion.rs +++ b/crates/analysis/src/completion.rs @@ -10,7 +10,9 @@ use zerosyntax_schema::ValueType; use zerosyntax_syntax::ast::{Block, Field, Module}; use zerosyntax_syntax::{Parse, SyntaxKind, SyntaxNode}; -use crate::model::scope_schema; +use crate::model::{ + is_model_asset_type, is_model_member_type, model_member_ini_name, models_in_scope, scope_schema, +}; use crate::{Analyzer, WorkspaceIndex}; /// The role of a completion item, mapped to LSP `CompletionItemKind` by the server. @@ -55,10 +57,20 @@ pub fn complete( scope_node, key, value_index, - } => field_value_completions(analyzer, &scope_node, &key, value_index, index, file), + current_token, + first_token, + } => field_value_completions( + analyzer, + &scope_node, + &key, + value_index, + (current_token.as_deref(), first_token.as_deref()), + index, + file, + ), PosContext::ModuleName { slot_accepts } => module_name_completions(analyzer, &slot_accepts), PosContext::SubBlockArg { argument_type } => { - completions_for_type(analyzer, &argument_type, 0, index) + completions_for_type(analyzer, &argument_type, 0, None, None, index) } } } @@ -74,6 +86,8 @@ enum PosContext { scope_node: SyntaxNode, key: String, value_index: usize, + current_token: Option, + first_token: Option, }, /// Completing a module type name after a slot `=`. Carries the slot's /// accepted interfaces so completions can be filtered to valid modules only. @@ -103,15 +117,27 @@ fn classify_position(analyzer: &Analyzer, root: &SyntaxNode, offset: u32) -> Pos .key() .map(|k| k.text().to_string()) .unwrap_or_default(); - let value_index = field - .value_tokens() + let value_tokens = field.value_tokens(); + let value_index = value_tokens .iter() - .filter(|t| u32::from(t.text_range().end()) <= offset) + .filter(|t| u32::from(t.text_range().end()) < offset) .count(); + let current_token = value_tokens + .iter() + .find(|t| { + let range = t.text_range(); + u32::from(range.start()) <= offset && offset <= u32::from(range.end()) + }) + .map(|t| t.text().trim_matches('"').to_string()); + let first_token = value_tokens + .first() + .map(|t| t.text().trim_matches('"').to_string()); return PosContext::FieldValue { scope_node: scope_node.unwrap_or_else(|| root.clone()), key, value_index, + current_token, + first_token, }; } return match scope_node { @@ -200,7 +226,7 @@ fn field_key_completions(analyzer: &Analyzer, scope_node: &SyntaxNode) -> Vec, Option<&str>), index: Option<&WorkspaceIndex>, file: Option<&str>, ) -> Vec { + let (current_token, first_token) = tokens; // RemoveModule / ReplaceModule: suggest module tags from the origin object. if key.eq_ignore_ascii_case("RemoveModule") || key.eq_ignore_ascii_case("ReplaceModule") { if let Some(idx) = index { @@ -296,10 +324,24 @@ fn field_value_completions( // DisplayName: add string table keys from the companion .str file when available. let mut base = { let scope = scope_schema(analyzer, scope_node); - scope - .field(key) - .map(|f| completions_for_type(analyzer, &f.value_type, value_index, index)) - .unwrap_or_default() + if let Some(f) = scope.field(key) { + if let Some(asset_completions) = + model_asset_completions(analyzer, scope_node, &f.value_type, value_index, index) + { + asset_completions + } else { + completions_for_type( + analyzer, + &f.value_type, + value_index, + current_token, + first_token, + index, + ) + } + } else { + Vec::new() + } }; if key.eq_ignore_ascii_case("DisplayName") { if let (Some(idx), Some(f)) = (index, file) { @@ -314,11 +356,90 @@ fn field_value_completions( base } +fn model_asset_completions( + analyzer: &Analyzer, + scope_node: &SyntaxNode, + ty: &ValueType, + value_index: usize, + index: Option<&WorkspaceIndex>, +) -> Option> { + let index = index?; + if !index.has_model_assets() { + return None; + } + let ty = token_value_type(ty, value_index); + if is_model_asset_type(ty) { + return Some( + index + .model_names() + .map(|name| Completion { + label: name.to_string(), + kind: CompletionKind::Reference, + detail: Some("W3D model".into()), + insert: None, + }) + .collect(), + ); + } + if !is_model_member_type(ty) { + return None; + } + let mut seen = std::collections::HashSet::new(); + let out = models_in_scope(analyzer, scope_node) + .into_iter() + .flat_map(|model| { + index + .model_members(&model) + .map(|member| model_member_ini_name(member).to_string()) + .collect::>() + }) + .filter(|member| seen.insert(member.to_ascii_lowercase())) + .map(|member| Completion { + label: member, + kind: CompletionKind::Reference, + detail: Some("W3D model member".into()), + insert: None, + }) + .collect(); + Some(out) +} + +fn token_value_type(ty: &ValueType, value_index: usize) -> &ValueType { + match ty { + ValueType::TokenList { tokens } => tokens.get(value_index).unwrap_or(ty), + _ => ty, + } +} + /// Build a single-token snippet placeholder for a value type, used when /// generating a full-sequence snippet for TokenList or structured types. /// `n` is the tab-stop index (1-based). fn type_snippet_placeholder(ty: &ValueType, n: usize) -> String { match ty { + ValueType::Prefixed { prefix, value_type } => { + if prefix.eq_ignore_ascii_case("Bone") + && matches!( + value_type.as_ref(), + ValueType::AsciiString | ValueType::QuotedString + ) + { + format!("{prefix}:${{{n}:NONE}}") + } else if prefix.eq_ignore_ascii_case("RandomBone") + && matches!(value_type.as_ref(), ValueType::Bool) + { + format!("{prefix}:${{{n}:No}}") + } else if prefix.eq_ignore_ascii_case("Loc") + && matches!(value_type.as_ref(), ValueType::AsciiString) + { + format!("{prefix}:X:${{{n}:0}}") + } else { + format!("{prefix}:{}", type_snippet_placeholder(value_type, n)) + } + } + ValueType::OneOf { variants } => variants + .first() + .map(|variant| type_snippet_placeholder(variant, n)) + .unwrap_or_else(|| format!("${{{n}:?}}")), ValueType::Bool => format!("${{{n}:Yes}}"), ValueType::Int | ValueType::UInt => format!("${{{n}:0}}"), ValueType::Real @@ -335,40 +456,106 @@ fn type_snippet_placeholder(ty: &ValueType, n: usize) -> String { ValueType::AsciiString | ValueType::AsciiStringList | ValueType::QuotedString => { format!("${{{n}:Value}}") } + ValueType::W3dModel => format!("${{{n}:Model}}"), + ValueType::W3dModelMember => format!("${{{n}:Bone}}"), _ => format!("${{{n}:?}}"), } } +fn value_snippet(ty: &ValueType) -> Option { + match ty { + ValueType::TokenList { tokens } if tokens.len() > 1 => { + let mut snippet = tokens + .iter() + .enumerate() + .map(|(i, t)| type_snippet_placeholder(t, i + 1)) + .collect::>() + .join(" "); + snippet.push_str("$0"); + Some(snippet) + } + ValueType::OneOf { variants } => variants.first().and_then(value_snippet), + _ => None, + } +} + fn completions_for_type( analyzer: &Analyzer, ty: &ValueType, value_index: usize, + current_token: Option<&str>, + first_token: Option<&str>, index: Option<&WorkspaceIndex>, ) -> Vec { match ty { + ValueType::OneOf { variants } => { + if current_token.is_some() || value_index > 0 { + return ty + .variant_for_first_token(first_token.or(current_token)) + .map(|variant| { + completions_for_type( + analyzer, + variant, + value_index, + current_token, + first_token, + index, + ) + }) + .unwrap_or_default(); + } + variants + .iter() + .flat_map(|variant| { + completions_for_type(analyzer, variant, 0, None, first_token, index) + }) + .collect() + } + ValueType::Prefixed { prefix, value_type } => { + let prefix_already_typed = current_token + .and_then(|t| t.split_once(':').map(|(actual, _)| actual)) + .is_some_and(|actual| actual.eq_ignore_ascii_case(prefix)); + completions_for_type( + analyzer, + value_type, + value_index, + current_token, + first_token, + index, + ) + .into_iter() + .map(|mut c| { + if !prefix_already_typed { + c.insert = Some(format!( + "{prefix}:{}", + c.insert.unwrap_or_else(|| c.label.clone()) + )); + } + c + }) + .collect() + } // Token lists: at position 0 offer a full-sequence snippet plus per-token completions. ValueType::TokenList { tokens } => { - let mut out = tokens - .get(value_index) - .map(|elem| completions_for_type(analyzer, elem, 0, index)) + let mut out = ty + .token_type_at(value_index) + .map(|elem| { + completions_for_type(analyzer, elem, 0, current_token, first_token, index) + }) .unwrap_or_default(); // At the first token, also inject a full-sequence snippet. - if value_index == 0 && tokens.len() > 1 { - let snippet: String = tokens - .iter() - .enumerate() - .map(|(i, t)| type_snippet_placeholder(t, i + 1)) - .collect::>() - .join(" "); - out.insert( - 0, - Completion { - label: "".into(), - kind: CompletionKind::Value, - detail: Some(format!("{} tokens", tokens.len())), - insert: Some(snippet), - }, - ); + if value_index == 0 { + if let Some(snippet) = value_snippet(ty) { + out.insert( + 0, + Completion { + label: "".into(), + kind: CompletionKind::Value, + detail: Some(format!("{} tokens", tokens.len())), + insert: Some(snippet), + }, + ); + } } out } @@ -437,6 +624,7 @@ fn completions_for_type( })); out } + ValueType::W3dModel | ValueType::W3dModelMember => Vec::new(), _ => Vec::new(), } } @@ -548,6 +736,16 @@ fn type_label(ty: &ValueType) -> String { ValueType::Enum { value_set } => format!("enum {value_set}"), ValueType::BitFlags { value_set } => format!("flags {value_set}"), ValueType::Reference { ref_kind } => format!("ref {ref_kind:?}"), + ValueType::W3dModel => "w3d model".into(), + ValueType::W3dModelMember => "w3d model member".into(), + ValueType::Prefixed { prefix, value_type } => { + format!("{prefix}:{}", type_label(value_type)) + } + ValueType::OneOf { variants } => variants + .iter() + .map(type_label) + .collect::>() + .join(" | "), other => format!("{other:?}") .split(['{', ' ']) .next() @@ -568,6 +766,27 @@ mod tests { .collect() } + fn item(src: &str, offset: u32, label: &str) -> Completion { + let a = Analyzer::embedded(); + complete(&a, &a.parse(src), offset, None, None) + .into_iter() + .find(|c| c.label == label) + .unwrap_or_else(|| panic!("missing completion `{label}`")) + } + + fn item_with_defs(src: &str, offset: u32, defs: &str, label: &str) -> Completion { + let a = Analyzer::embedded(); + let mut index = WorkspaceIndex::new(); + index.set_file( + "defs.ini", + crate::index::definitions_in(&a, &a.parse(defs), "defs.ini"), + ); + complete(&a, &a.parse(src), offset, Some(&index), None) + .into_iter() + .find(|c| c.label == label) + .unwrap_or_else(|| panic!("missing completion `{label}`")) + } + #[test] fn top_level_suggests_block_keywords() { let out = labels("", 0); @@ -612,4 +831,174 @@ mod tests { let out = labels(src, offset); assert!(out.contains(&"ActiveBody".to_string()), "{out:?}"); } + + #[test] + fn model_asset_completions_use_index() { + let a = Analyzer::embedded(); + let mut index = WorkspaceIndex::new(); + index.set_file_models( + "models/Good.w3d", + vec![crate::index::ModelAsset { + name: "Good".into(), + members: vec!["Cargo01".into(), "Tire01".into()], + }], + ); + let src = "\ +Object Tank + Draw = W3DTruckDraw ModuleTag_01 + DefaultConditionState + Model = + HideSubObject = + End + End +End +"; + let model_offset = src.find("Model = ").unwrap() + "Model = ".len(); + let out: Vec<_> = complete(&a, &a.parse(src), model_offset as u32, Some(&index), None) + .into_iter() + .map(|c| c.label) + .collect(); + assert!(out.contains(&"Good".to_string()), "{out:?}"); + + let src = src.replace("Model = ", "Model = Good"); + let bone_offset = src.find("HideSubObject = ").unwrap() + "HideSubObject = ".len(); + let out: Vec<_> = complete(&a, &a.parse(&src), bone_offset as u32, Some(&index), None) + .into_iter() + .map(|c| c.label) + .collect(); + assert!(out.contains(&"Cargo".to_string()), "{out:?}"); + assert!(out.contains(&"Tire".to_string()), "{out:?}"); + } + + #[test] + fn model_completions_inside_named_condition_state() { + let a = Analyzer::embedded(); + let mut index = WorkspaceIndex::new(); + index.set_file_models( + "models/Good.w3d", + vec![crate::index::ModelAsset { + name: "Good".into(), + members: vec!["Turret01".into()], + }], + ); + let src = "\ +Object Tank + Draw = W3DTankDraw ModuleTag_01 + DefaultConditionState + Model = Good + End + ConditionState = DAMAGED + Model = + End + End +End +"; + let offset = src + .find("ConditionState = DAMAGED\n Model = ") + .unwrap() + + "ConditionState = DAMAGED\n Model = ".len(); + let out: Vec<_> = complete(&a, &a.parse(src), offset as u32, Some(&index), None) + .into_iter() + .map(|c| c.label) + .collect(); + assert!(out.contains(&"Good".to_string()), "{out:?}"); + } + + #[test] + fn weapon_bone_completions_use_token_positions() { + let a = Analyzer::embedded(); + let mut index = WorkspaceIndex::new(); + index.set_file_models( + "models/Good.w3d", + vec![crate::index::ModelAsset { + name: "Good".into(), + members: vec!["Muzzle01".into(), "Muzzle02".into()], + }], + ); + let src = "\ +Object Tank + Draw = W3DTruckDraw ModuleTag_01 + DefaultConditionState + Model = Good + WeaponFireFXBone = + End + End +End +"; + let slot_offset = src.find("WeaponFireFXBone = ").unwrap() + "WeaponFireFXBone = ".len(); + let out: Vec<_> = complete(&a, &a.parse(src), slot_offset as u32, Some(&index), None) + .into_iter() + .map(|c| c.label) + .collect(); + assert!(out.contains(&"PRIMARY".to_string()), "{out:?}"); + assert!(!out.contains(&"Muzzle".to_string()), "{out:?}"); + + let src = src.replace("WeaponFireFXBone = ", "WeaponFireFXBone = PRIMARY "); + let bone_offset = src.find("PRIMARY ").unwrap() + "PRIMARY ".len(); + let out: Vec<_> = complete(&a, &a.parse(&src), bone_offset as u32, Some(&index), None) + .into_iter() + .map(|c| c.label) + .collect(); + assert!(out.contains(&"Muzzle".to_string()), "{out:?}"); + assert_eq!( + out.iter() + .filter(|label| label.as_str() == "Muzzle") + .count(), + 1 + ); + assert!(!out.contains(&"PRIMARY".to_string()), "{out:?}"); + } + + #[test] + fn transition_damage_particle_field_inserts_full_snippet() { + let src = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n \n End\nEnd\n"; + let offset = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n ".len() as u32; + let got = item(src, offset, "DamagedParticleSystem1"); + assert_eq!( + got.insert.as_deref(), + Some( + "DamagedParticleSystem1 = Bone:${1:NONE} RandomBone:${2:No} PSys:${3:ParticleSystem}$0" + ) + ); + } + + #[test] + fn transition_damage_fx_and_ocl_fields_insert_full_snippets() { + let src = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n \n End\nEnd\n"; + let offset = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n ".len() as u32; + assert_eq!( + item(src, offset, "DamagedFXList1").insert.as_deref(), + Some("DamagedFXList1 = Bone:${1:NONE} RandomBone:${2:No} FXList:${3:FxList}$0") + ); + assert_eq!( + item(src, offset, "DamagedOCL10").insert.as_deref(), + Some("DamagedOCL10 = Bone:${1:NONE} RandomBone:${2:No} OCL:${3:ObjectCreationList}$0") + ); + } + + #[test] + fn prefixed_particle_reference_suggests_while_typing() { + let src = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n DamagedParticleSystem1 = Bone:NONE RandomBone:No PSys:Str\n End\nEnd\n"; + let offset = src.find("PSys:Str").unwrap() + "PSys:Str".len(); + let got = item_with_defs( + src, + offset as u32, + "ParticleSystem StructureTransitionMediumSmoke\nEnd\n", + "StructureTransitionMediumSmoke", + ); + assert_eq!(got.insert, None); + } + + #[test] + fn loc_variant_reference_suggests_while_typing() { + let src = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n DamagedFXList1 = Loc:X:0.0 Y:0.0 Z:0.0 FXList:FX_\n End\nEnd\n"; + let offset = src.find("FXList:FX_").unwrap() + "FXList:FX_".len(); + let got = item_with_defs( + src, + offset as u32, + "FXList FX_TankDamageTransition\nEnd\n", + "FX_TankDamageTransition", + ); + assert_eq!(got.insert, None); + } } diff --git a/crates/analysis/src/diagnostics.rs b/crates/analysis/src/diagnostics.rs index c6546f7..4804115 100644 --- a/crates/analysis/src/diagnostics.rs +++ b/crates/analysis/src/diagnostics.rs @@ -20,7 +20,10 @@ use zerosyntax_schema::{RefKind, ValueType}; use zerosyntax_syntax::ast::{Block, Field, Module}; use zerosyntax_syntax::{Parse, SyntaxKind, SyntaxNode, SyntaxToken}; -use crate::model::{module_fits_slot, scope_schema, ScopeSchema}; +use crate::model::{ + is_model_asset_type, is_model_member_type, model_member_matches, models_in_scope, + module_fits_slot, scope_schema, ScopeSchema, +}; use crate::{Analyzer, Span, WorkspaceIndex}; /// Severity of a diagnostic, mapped to LSP severities by the server. @@ -88,7 +91,10 @@ pub const KNOWN_CODES: &[&str] = &[ "bad-number", "bad-enum", "bad-flag", + "bad-prefixed", "unresolved-reference", + "unknown-model", + "unknown-model-member", "unknown-suppression", "module-wrong-slot", "duplicate-module-tag", @@ -649,6 +655,7 @@ impl<'a> Ctx<'a> { const ARMOR_TRIGGERS: [&str; 1] = ["ArmorUpgrade"]; let mut module_names: Vec = Vec::new(); + let mut weapon_set_upgrade_modules: Vec = Vec::new(); // (set keyword, the PLAYER_UPGRADE condition token) per set sub-block. let mut player_upgrade_sets: Vec<(&'static str, SyntaxToken)> = Vec::new(); let mut is_override_patch = has_direct_field(node, "RemoveModule"); @@ -670,6 +677,9 @@ impl<'a> Ctx<'a> { } _ => { if let Some(name) = module.module_name() { + if name.text() == "WeaponSetUpgrade" { + weapon_set_upgrade_modules.push(name.clone()); + } module_names.push(name.text().to_string()); } } @@ -678,6 +688,17 @@ impl<'a> Ctx<'a> { if is_override_patch { return; } + let has_player_upgrade_weapon_set = + player_upgrade_sets.iter().any(|(kw, _)| *kw == "WeaponSet"); + if !has_player_upgrade_weapon_set { + for tok in weapon_set_upgrade_modules { + self.warning( + &tok, + "unreachable-set", + "this `WeaponSetUpgrade` module sets `PLAYER_UPGRADE`, but this object has no `WeaponSet` with that condition".to_string(), + ); + } + } for (kw, tok) in player_upgrade_sets { let triggers: &[&str] = if kw == "WeaponSet" { &WEAPON_TRIGGERS @@ -703,7 +724,7 @@ impl<'a> Ctx<'a> { fn walk(&mut self, node: &SyntaxNode, scope: &ScopeSchema) { for child in node.children() { match child.kind() { - SyntaxKind::FIELD => self.field(&child, scope), + SyntaxKind::FIELD => self.field(&child, scope, node), SyntaxKind::MODULE => self.module(&child, scope), SyntaxKind::BLOCK => { // Blocks nested in blocks are unusual but handled for safety. @@ -715,13 +736,14 @@ impl<'a> Ctx<'a> { } } - fn field(&mut self, node: &SyntaxNode, scope: &ScopeSchema) { + fn field(&mut self, node: &SyntaxNode, scope: &ScopeSchema, scope_node: &SyntaxNode) { let field = Field(node.clone()); let Some(key) = field.key() else { return }; let name = key.text(); if let Some(schema_field) = scope.field(name) { self.validate_value(&field, &schema_field.value_type); + self.validate_model_asset(&field, schema_field, scope_node); } else if scope.has_field_schema() && !scope.module_slots().iter().any(|s| s.keyword == name) { @@ -733,6 +755,81 @@ impl<'a> Ctx<'a> { } } + fn validate_model_asset( + &mut self, + field: &Field, + schema_field: &zerosyntax_schema::Field, + scope_node: &SyntaxNode, + ) { + let Some(index) = self.index else { return }; + if !index.has_model_assets() { + return; + } + let tokens = field.value_tokens(); + match &schema_field.value_type { + ValueType::TokenList { tokens: specs } => { + for (spec, tok) in specs.iter().zip(tokens.iter()) { + self.validate_model_asset_token(spec, tok, scope_node); + } + } + ty => { + if let Some(tok) = tokens.first() { + self.validate_model_asset_token(ty, tok, scope_node); + } + } + } + } + + fn validate_model_asset_token( + &mut self, + ty: &ValueType, + tok: &SyntaxToken, + scope_node: &SyntaxNode, + ) { + let Some(index) = self.index else { return }; + let value = unquote(tok.text()); + if value.is_empty() || value.eq_ignore_ascii_case("None") { + return; + } + if is_model_asset_type(ty) { + if !index.is_model_asset(value) { + self.warning( + tok, + "unknown-model", + format!("`{value}` is not a known W3D model asset"), + ); + } + return; + } + if !is_model_member_type(ty) { + return; + } + let models = models_in_scope(self.analyzer, scope_node); + if models.is_empty() { + return; + } + let mut checked_any_model = false; + for model in models { + if !index.is_model_asset(&model) { + continue; + } + checked_any_model = true; + if index + .model_members(&model) + .any(|member| model_member_matches(member, value)) + { + return; + } + } + if checked_any_model { + self.warning( + tok, + "unknown-model-member", + format!("`{value}` is not a known W3D model bone or subobject"), + ); + } + } + fn module(&mut self, node: &SyntaxNode, parent: &ScopeSchema) { let module = Module(node.clone()); // A MODULE node is a *real* module only when its slot keyword is one of @@ -852,6 +949,9 @@ impl<'a> Ctx<'a> { // but 5 of 862 cases, so the omission is almost always an accident. // (Not checked for ArmorSet: omitting it there is common practice.) if let ScopeSchema::SubBlock(sb) = &inner { + if let Some(argument_type) = &sb.argument_type { + self.validate_sub_block_argument(&module, argument_type); + } if sb.keyword == "WeaponSet" && !has_direct_field(node, "Conditions") { if let Some(slot) = module.slot() { self.warning( @@ -868,6 +968,33 @@ impl<'a> Ctx<'a> { self.walk(node, &inner); } + fn validate_sub_block_argument(&mut self, module: &Module, ty: &ValueType) { + let tokens = module.argument_tokens(); + if tokens.is_empty() { + return; + } + match ty { + ValueType::BitFlags { .. } | ValueType::ReferenceList { .. } => { + for token in &tokens { + self.check_token(token, ty); + } + } + ValueType::TokenList { tokens: specs } => { + for (token, spec) in tokens.iter().zip(specs) { + self.check_token(token, spec); + } + } + ValueType::OneOf { .. } => { + if let Some(variant) = + ty.variant_for_first_token(tokens.first().map(|t| unquote(t.text()))) + { + self.check_token(&tokens[0], variant); + } + } + single => self.check_token(&tokens[0], single), + } + } + /// Validate a field's value tokens against its declared type. fn validate_value(&mut self, field: &Field, ty: &ValueType) { let tokens = field.value_tokens(); @@ -885,6 +1012,13 @@ impl<'a> Ctx<'a> { return; } match ty { + ValueType::OneOf { .. } => { + if let Some(variant) = + ty.variant_for_first_token(tokens.first().map(|t| unquote(t.text()))) + { + self.validate_value(field, variant); + } + } ValueType::BitFlags { value_set } => { for tok in &tokens { let raw = tok.text().trim_start_matches(['+', '-']); @@ -923,6 +1057,14 @@ impl<'a> Ctx<'a> { } } } + if let Some(spec) = specs + .last() + .filter(|spec| matches!(spec, ValueType::BitFlags { .. })) + { + for tok in tokens.iter().skip(specs.len()) { + self.check_token(tok, spec); + } + } } // `R:0 G:0 B:0 [A:255]` — components are ints in 0..=255, the `A` // component is optional (INI.cpp parseRGBColor / parseColorInt). @@ -991,18 +1133,123 @@ impl<'a> Ctx<'a> { ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } => { self.check_reference(*ref_kind, tok) } + ValueType::Prefixed { prefix, value_type } => { + self.check_prefixed_token(tok, prefix, value_type) + } // No single-token validation for these. ValueType::AsciiString | ValueType::QuotedString | ValueType::AsciiStringList + | ValueType::W3dModel + | ValueType::W3dModelMember | ValueType::Color | ValueType::Coord2D | ValueType::Coord3D | ValueType::TokenList { .. } + | ValueType::OneOf { .. } | ValueType::Unknown { .. } => {} } } + fn check_prefixed_token(&mut self, tok: &SyntaxToken, prefix: &str, ty: &ValueType) { + let text = unquote(tok.text()); + let Some((actual, value)) = text.split_once(':') else { + self.error( + tok, + "bad-prefixed", + format!("expected `{prefix}:...`, found `{text}`"), + ); + return; + }; + if !actual.eq_ignore_ascii_case(prefix) { + self.error( + tok, + "bad-prefixed", + format!("expected `{prefix}:...`, found `{text}`"), + ); + return; + } + if prefix.eq_ignore_ascii_case("Loc") { + let Some((axis, n)) = value.split_once(':') else { + self.error( + tok, + "bad-prefixed", + format!("expected `Loc:X:`, found `{text}`"), + ); + return; + }; + if !axis.eq_ignore_ascii_case("X") { + self.error( + tok, + "bad-prefixed", + format!("expected `Loc:X:`, found `{text}`"), + ); + return; + } + if n.parse::().is_err() { + self.error( + tok, + "bad-number", + format!("expected a number for `Loc:X:`, found `{n}`"), + ); + } + return; + } + match ty { + ValueType::Bool => { + let v = value.to_ascii_lowercase(); + if v != "yes" && v != "no" { + self.error( + tok, + "bad-bool", + format!("expected `Yes` or `No`, found `{value}`"), + ); + } + } + ValueType::Int => self.check_prefixed_number(tok, prefix, value, NumKind::Int), + ValueType::UInt => self.check_prefixed_number(tok, prefix, value, NumKind::UInt), + ValueType::Real + | ValueType::PositiveReal + | ValueType::AngleReal + | ValueType::Velocity + | ValueType::Acceleration + | ValueType::Duration => self.check_prefixed_number(tok, prefix, value, NumKind::Real), + ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } => { + self.check_reference_name(*ref_kind, tok, value) + } + ValueType::Enum { value_set } => self.check_enum_member_name(value_set, tok, value), + ValueType::BitFlags { value_set } => { + let raw = value.trim_start_matches(['+', '-']); + if !raw.eq_ignore_ascii_case("NONE") && !raw.eq_ignore_ascii_case("ALL") { + self.check_bitflag_member_name(value_set, tok, raw); + } + } + ValueType::AsciiString | ValueType::AsciiStringList | ValueType::QuotedString => {} + _ => {} + } + } + + fn check_prefixed_number( + &mut self, + tok: &SyntaxToken, + prefix: &str, + value: &str, + kind: NumKind, + ) { + let ok = match kind { + NumKind::Int => value.parse::().is_ok(), + NumKind::UInt => value.parse::().is_ok(), + NumKind::Real => value.parse::().is_ok(), + }; + if !ok { + self.error( + tok, + "bad-number", + format!("expected a number for `{prefix}:`, found `{value}`"), + ); + } + } + /// Validate a tagged-axis value (`R:255 G:0 B:0`, `X:1 Y:2 Z:3`). The /// engine tokenizes with `:` as a separator, so `R:255`, `R: 255` and /// `R : 255` are all accepted; tags match case-insensitively and in order. @@ -1119,13 +1366,16 @@ impl<'a> Ctx<'a> { } fn check_enum_member(&mut self, value_set: &str, tok: &SyntaxToken) { + self.check_enum_member_name(value_set, tok, tok.text()); + } + + fn check_enum_member_name(&mut self, value_set: &str, tok: &SyntaxToken, v: &str) { let Some(set) = self.analyzer.value_set(value_set) else { return; }; if set.members.is_empty() { return; // value set we couldn't populate; don't flag } - let v = tok.text(); if !set.members.iter().any(|m| m.name.eq_ignore_ascii_case(v)) { self.error( tok, @@ -1136,6 +1386,10 @@ impl<'a> Ctx<'a> { } fn check_bitflag_member(&mut self, value_set: &str, tok: &SyntaxToken, raw: &str) { + self.check_bitflag_member_name(value_set, tok, raw); + } + + fn check_bitflag_member_name(&mut self, value_set: &str, tok: &SyntaxToken, raw: &str) { let Some(set) = self.analyzer.value_set(value_set) else { return; }; @@ -1152,8 +1406,11 @@ impl<'a> Ctx<'a> { } fn check_reference(&mut self, kind: RefKind, tok: &SyntaxToken) { + self.check_reference_name(kind, tok, unquote(tok.text())); + } + + fn check_reference_name(&mut self, kind: RefKind, tok: &SyntaxToken, name: &str) { let Some(index) = self.index else { return }; - let name = unquote(tok.text()); // `None` is the universal null reference; `NoSound` is the audio one; // builtins (e.g. `Upgrade_Veterancy_*`) exist in no file by design. if name.is_empty() @@ -1296,6 +1553,27 @@ mod tests { assert!(!codes(vet).contains(&"unreachable-set")); } + #[test] + fn weapon_set_upgrade_without_player_upgrade_weapon_set_warns() { + let src = "\ +Object T + WeaponSet + Conditions = NONE + Weapon = PRIMARY G + End + Behavior = WeaponSetUpgrade ModuleTag_01 + TriggeredBy = Upgrade_X + End +End +"; + let d = diags(src); + assert!(d.iter().any(|d| { + d.code == "unreachable-set" + && d.severity == Severity::Warning + && &src[d.span.start as usize..d.span.end as usize] == "WeaponSetUpgrade" + })); + } + #[test] fn unknown_field_is_warning() { let src = "Weapon AK47\n PrimaryDamg = 50.0\nEnd\n"; @@ -1345,6 +1623,54 @@ End assert!(c.contains(&"unknown-field"), "{c:?}"); } + #[test] + fn transition_damage_particle_tokens_are_validated() { + let ok = "\ +Object Tank + Behavior = TransitionDamageFX ModuleTag_01 + DamagedParticleSystem1 = Bone:NONE RandomBone:No PSys:StructureTransitionMediumSmoke + End +End +"; + let ok_codes = codes(ok); + assert!(!ok_codes.contains(&"bad-prefixed"), "{ok_codes:?}"); + assert!(!ok_codes.contains(&"bad-bool"), "{ok_codes:?}"); + + let bad = "\ +Object Tank + Behavior = TransitionDamageFX ModuleTag_01 + DamagedParticleSystem1 = Bone:NONE RandomBone:Maybe ParticleSystem:StructureTransitionMediumSmoke + End +End +"; + let bad_codes = codes(bad); + assert!(bad_codes.contains(&"bad-bool"), "{bad_codes:?}"); + assert!(bad_codes.contains(&"bad-prefixed"), "{bad_codes:?}"); + } + + #[test] + fn transition_damage_loc_tokens_are_validated() { + let ok = "\ +Object Tank + Behavior = TransitionDamageFX ModuleTag_01 + DamagedFXList1 = Loc:X:0.0 Y:0.0 Z:0.0 FXList:FX_TankDamageTransition + End +End +"; + let ok_codes = codes(ok); + assert!(!ok_codes.contains(&"bad-prefixed"), "{ok_codes:?}"); + assert!(!ok_codes.contains(&"bad-number"), "{ok_codes:?}"); + + let bad = "\ +Object Tank + Behavior = TransitionDamageFX ModuleTag_01 + DamagedFXList1 = Loc:X:0.0 Y:nope Z:0.0 FXList:FX_TankDamageTransition + End +End +"; + assert!(codes(bad).contains(&"bad-number")); + } + #[test] fn unknown_module_warns() { let src = "Object Tank\n Body = NotARealModule Tag01\n End\nEnd\n"; @@ -1587,4 +1913,107 @@ End ); assert!(index.is_defined(RefKind::Weapon, "AK47")); } + + #[test] + fn model_assets_validate_models_and_members_when_indexed() { + let a = Analyzer::embedded(); + let mut index = WorkspaceIndex::new(); + index.set_file_models( + "models/Good.w3d", + vec![crate::index::ModelAsset { + name: "Good".into(), + members: vec!["Tire01".into(), "Cargo01".into(), "Muzzle01".into()], + }], + ); + let src = "\ +Object Tank + Draw = W3DTruckDraw ModuleTag_01 + DefaultConditionState + Model = MissingModel + HideSubObject = MissingBone + WeaponFireFXBone = PRIMARY Muzzle + WeaponLaunchBone = BAD_SLOT Muzzle + WeaponRecoilBone = PRIMARY MissingMuzzle + End + End +End +"; + let parse = a.parse(src); + let diags = diagnose(&a, &parse, Some(&index), Some("test.ini")); + assert!(diags.iter().any(|d| d.code == "unknown-model"), "{diags:?}"); + assert!( + !diags.iter().any(|d| d.code == "unknown-model-member"), + "unknown model should not cascade into member warnings: {diags:?}" + ); + + let src = src.replace("MissingModel", "Good"); + let parse = a.parse(&src); + let diags = diagnose(&a, &parse, Some(&index), Some("test.ini")); + assert!( + diags.iter().any(|d| d.code == "unknown-model-member"), + "{diags:?}" + ); + assert!( + diags.iter().any(|d| { + d.code == "bad-enum" + && &src[d.span.start as usize..d.span.end as usize] == "BAD_SLOT" + }), + "{diags:?}" + ); + assert!( + diags.iter().any(|d| { + d.code == "unknown-model-member" + && &src[d.span.start as usize..d.span.end as usize] == "MissingMuzzle" + }), + "{diags:?}" + ); + assert!(!diags.iter().any(|d| { + d.code == "unknown-model-member" + && &src[d.span.start as usize..d.span.end as usize] == "Muzzle" + })); + } + + #[test] + fn condition_state_inherits_model_from_sibling_default_state() { + // Real game data: a ConditionState that sets no Model inherits the + // DefaultConditionState's model, so its bones validate against it. + let a = Analyzer::embedded(); + let mut index = WorkspaceIndex::new(); + index.set_file_models( + "models/Good.w3d", + vec![crate::index::ModelAsset { + name: "Good".into(), + members: vec!["Turret01".into()], + }], + ); + let src = "\ +Object Tank + Draw = W3DTankDraw ModuleTag_01 + DefaultConditionState + Model = Good + End + ConditionState = DAMAGED + HideSubObject = Turret01 + ShowSubObject = MissingBone + End + End +End +"; + let parse = a.parse(src); + let diags = diagnose(&a, &parse, Some(&index), Some("test.ini")); + assert!( + !diags.iter().any(|d| { + d.code == "unknown-model-member" + && &src[d.span.start as usize..d.span.end as usize] == "Turret01" + }), + "{diags:?}" + ); + assert!( + diags.iter().any(|d| { + d.code == "unknown-model-member" + && &src[d.span.start as usize..d.span.end as usize] == "MissingBone" + }), + "{diags:?}" + ); + } } diff --git a/crates/analysis/src/index.rs b/crates/analysis/src/index.rs index 3cf2634..4dbc964 100644 --- a/crates/analysis/src/index.rs +++ b/crates/analysis/src/index.rs @@ -9,11 +9,18 @@ use std::collections::HashMap; use zerosyntax_schema::{RefKind, ValueType}; use zerosyntax_syntax::ast::{Block, Field, Module}; -use zerosyntax_syntax::{Parse, SyntaxKind, SyntaxNode}; +use zerosyntax_syntax::{Parse, SyntaxKind, SyntaxNode, SyntaxToken}; use crate::model::{scope_schema, ScopeSchema}; use crate::{Analyzer, Span}; +/// Model data discovered from a W3D asset. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModelAsset { + pub name: String, + pub members: Vec, +} + /// A definition's location within a file. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Location { @@ -73,6 +80,13 @@ pub struct WorkspaceIndex { /// String table keys from companion `.str` files, keyed by the INI file URI. /// Powers DisplayName completions when a map.str is present. ini_str_keys: HashMap>, + /// W3D model assets, keyed case-insensitively by model name. Each entry + /// keeps the per-file contributions, so re-indexing or removing one asset + /// file (e.g. a patch archive overriding a base-game model) never drops + /// another file's model of the same name. + model_assets: HashMap>, + /// Reverse map for removing/replacing models contributed by one asset file. + file_models: HashMap>, } impl WorkspaceIndex { @@ -140,11 +154,14 @@ impl WorkspaceIndex { /// Drop all definitions contributed by `file`. pub fn remove_file(&mut self, file: &str) { - if self.files.get(file).is_some_and(|v| !v.is_empty()) { + if self.files.get(file).is_some_and(|v| !v.is_empty()) + || self.file_models.get(file).is_some_and(|v| !v.is_empty()) + { self.generation += 1; } self.remove_entries(file); self.remove_site_entries(file); + self.remove_model_entries(file); } fn remove_site_entries(&mut self, file: &str) { @@ -175,6 +192,45 @@ impl WorkspaceIndex { } } + /// Replace W3D model assets contributed by `file`. + pub fn set_file_models(&mut self, file: &str, models: Vec) { + let normalized = normalized_model_assets(&models); + let changed = match self.file_models.get(file) { + Some(old) => normalized_model_assets(old) != normalized, + None => !models.is_empty(), + }; + if changed { + self.generation += 1; + } + self.remove_model_entries(file); + let mut stored = Vec::with_capacity(models.len()); + for mut model in models { + dedup_case_insensitive(&mut model.members); + self.model_assets + .entry(model.name.to_ascii_lowercase()) + .or_default() + .push((file.to_string(), model.clone())); + stored.push(model); + } + if !stored.is_empty() { + self.file_models.insert(file.to_string(), stored); + } + } + + fn remove_model_entries(&mut self, file: &str) { + if let Some(models) = self.file_models.remove(file) { + for model in models { + let lower = model.name.to_ascii_lowercase(); + if let Some(contribs) = self.model_assets.get_mut(&lower) { + contribs.retain(|(f, _)| f != file); + if contribs.is_empty() { + self.model_assets.remove(&lower); + } + } + } + } + } + /// Replace module-tag entries contributed by `file`. /// Called alongside `set_file` so RemoveModule completions stay current. pub fn set_file_tags(&mut self, file: &str, tags: Vec<(String, String)>) { @@ -228,6 +284,35 @@ impl WorkspaceIndex { .flat_map(|keys| keys.iter().map(|k| k.as_str())) } + /// Whether any W3D model assets have been indexed. + pub fn has_model_assets(&self) -> bool { + !self.model_assets.is_empty() + } + + /// Is a W3D model known from indexed assets? + pub fn is_model_asset(&self, name: &str) -> bool { + self.model_assets.contains_key(&name.to_ascii_lowercase()) + } + + /// Known W3D model names, in display casing. + pub fn model_names(&self) -> impl Iterator { + self.model_assets + .values() + .filter_map(|contribs| contribs.first()) + .map(|(_, m)| m.name.as_str()) + } + + /// User-addressable members (pivots/subobjects/meshes) for `model`, + /// across every file that contributes the model. May repeat a member + /// when several files define the same model; callers dedup or use `any`. + pub fn model_members<'a>(&'a self, model: &str) -> impl Iterator { + self.model_assets + .get(&model.to_ascii_lowercase()) + .into_iter() + .flatten() + .flat_map(|(_, m)| m.members.iter().map(|b| b.as_str())) + } + /// Is `name` defined for `kind` anywhere in the workspace? /// Case-insensitive, like the engine's own name lookups. pub fn is_defined(&self, kind: RefKind, name: &str) -> bool { @@ -291,6 +376,29 @@ impl WorkspaceIndex { } } +fn dedup_case_insensitive(values: &mut Vec) { + let mut seen = std::collections::HashSet::new(); + values.retain(|value| seen.insert(value.to_ascii_lowercase())); +} + +fn normalized_model_assets(models: &[ModelAsset]) -> Vec<(String, Vec)> { + let mut out = models + .iter() + .map(|model| { + let mut members = model + .members + .iter() + .map(|member| member.to_ascii_lowercase()) + .collect::>(); + members.sort(); + members.dedup(); + (model.name.to_ascii_lowercase(), members) + }) + .collect::>(); + out.sort(); + out +} + /// Collect every reference site in a parsed document: each value token of a /// `Reference`/`ReferenceList`-typed field (including reference elements of /// `token_list` fields). Null sentinels (`None`, audio `NoSound`) and engine @@ -328,8 +436,7 @@ fn collect_field_refs( return; }; let tokens = field.value_tokens(); - let mut push = |kind: RefKind, tok: &zerosyntax_syntax::SyntaxToken| { - let name = tok.text().trim_matches('"'); + let mut push = |kind: RefKind, name: &str, span: Span| { if name.is_empty() || name.eq_ignore_ascii_case("None") || (kind == RefKind::AudioEvent && name.eq_ignore_ascii_case("NoSound")) @@ -340,26 +447,79 @@ fn collect_field_refs( out.push(ReferenceSite { name: name.to_string(), kind, - span: tok.text_range().into(), + span, }); }; - match &schema_field.value_type { + collect_refs_from_type(&schema_field.value_type, &tokens, &mut push); +} + +fn collect_refs_from_type( + ty: &ValueType, + tokens: &[SyntaxToken], + push: &mut impl FnMut(RefKind, &str, Span), +) { + match ty { + ValueType::OneOf { .. } => { + if let Some(variant) = + ty.variant_for_first_token(tokens.first().map(|t| t.text().trim_matches('"'))) + { + collect_refs_from_type(variant, tokens, push); + } + } ValueType::Reference { ref_kind } => { if let Some(tok) = tokens.first() { - push(*ref_kind, tok); + push( + *ref_kind, + tok.text().trim_matches('"'), + tok.text_range().into(), + ); } } ValueType::ReferenceList { ref_kind } => { - for tok in &tokens { - push(*ref_kind, tok); + for tok in tokens { + push( + *ref_kind, + tok.text().trim_matches('"'), + tok.text_range().into(), + ); } } ValueType::TokenList { tokens: specs } => { for (spec, tok) in specs.iter().zip(tokens.iter()) { - if let ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } = - spec - { - push(*ref_kind, tok); + match spec { + ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } => { + push( + *ref_kind, + tok.text().trim_matches('"'), + tok.text_range().into(), + ); + } + ValueType::Prefixed { prefix, value_type } => { + if let ValueType::Reference { ref_kind } + | ValueType::ReferenceList { ref_kind } = value_type.as_ref() + { + let text = tok.text().trim_matches('"'); + let Some((actual, name)) = text.split_once(':') else { + continue; + }; + if !actual.eq_ignore_ascii_case(prefix) { + continue; + } + let start = u32::from(tok.text_range().start()) + + u32::from(tok.text().starts_with('"')) + + actual.len() as u32 + + 1; + push( + *ref_kind, + name, + Span { + start, + end: start + name.len() as u32, + }, + ); + } + } + _ => {} } } } @@ -495,6 +655,22 @@ mod tests { assert!(!idx.is_referenced(RefKind::Upgrade, "Upgrade_A")); } + #[test] + fn quoted_prefixed_reference_site_span_excludes_quotes_and_prefix() { + let a = Analyzer::embedded(); + let src = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n DamagedParticleSystem1 = Bone:NONE RandomBone:No \"PSys:MissingParticle\"\n End\nEnd\n"; + let refs = references_in(&a, &a.parse(src)); + let reference = refs + .iter() + .find(|reference| reference.name == "MissingParticle") + .unwrap(); + assert_eq!(reference.kind, RefKind::ParticleSystem); + assert_eq!( + &src[reference.span.start as usize..reference.span.end as usize], + "MissingParticle" + ); + } + #[test] fn workspace_symbols_match_by_substring() { let a = Analyzer::embedded(); @@ -528,4 +704,63 @@ mod tests { assert!(!idx.is_defined(RefKind::Weapon, "Old")); assert!(idx.is_defined(RefKind::Weapon, "New")); } + + #[test] + fn model_asset_member_changes_bump_generation() { + let mut idx = WorkspaceIndex::new(); + idx.set_file_models( + "model.w3d", + vec![ModelAsset { + name: "Tank".into(), + members: vec!["Tire01".into()], + }], + ); + let g1 = idx.generation(); + idx.set_file_models( + "model.w3d", + vec![ModelAsset { + name: "Tank".into(), + members: vec!["Tire02".into()], + }], + ); + assert_ne!(idx.generation(), g1); + } + + #[test] + fn removing_one_file_keeps_other_files_models_of_same_name() { + // Base game and a patch archive both ship a model called "Tank" + // (patches overriding base models is the normal case). + let mut idx = WorkspaceIndex::new(); + idx.set_file_models( + "base.w3d", + vec![ModelAsset { + name: "Tank".into(), + members: vec!["Tire01".into()], + }], + ); + idx.set_file_models( + "patch.w3d", + vec![ModelAsset { + name: "TANK".into(), + members: vec!["Cargo01".into()], + }], + ); + let members: Vec<_> = idx.model_members("tank").collect(); + assert!(members.contains(&"Tire01") && members.contains(&"Cargo01")); + + idx.remove_file("patch.w3d"); + assert!(idx.is_model_asset("Tank")); + let members: Vec<_> = idx.model_members("Tank").collect(); + assert_eq!(members, vec!["Tire01"]); + + // Re-indexing the remaining file (a rescan) must not lose it either. + idx.set_file_models( + "base.w3d", + vec![ModelAsset { + name: "Tank".into(), + members: vec!["Tire01".into()], + }], + ); + assert!(idx.is_model_asset("Tank")); + } } diff --git a/crates/analysis/src/model.rs b/crates/analysis/src/model.rs index b59eb73..53eaf3c 100644 --- a/crates/analysis/src/model.rs +++ b/crates/analysis/src/model.rs @@ -1,7 +1,8 @@ //! Bridges the syntax tree to the schema: given a scope node (a `BLOCK` or //! `MODULE`), determine which schema entity it is and look up fields / slots. -use zerosyntax_schema::{BlockType, Field, ModuleSlot, ModuleType, SubBlock}; +use zerosyntax_schema::{BlockType, Field, ModuleSlot, ModuleType, SubBlock, ValueType}; +use zerosyntax_syntax::ast::Field as AstField; /// Returns true when `module` implements at least one of the interfaces the /// `slot` accepts. Used to filter completions and validate module placement. @@ -139,3 +140,80 @@ pub fn enclosing_scopes<'a>(analyzer: &'a Analyzer, node: &SyntaxNode) -> Vec bool { + matches!(ty, ValueType::W3dModel) +} + +pub(crate) fn is_model_member_type(ty: &ValueType) -> bool { + matches!(ty, ValueType::W3dModelMember) +} + +pub(crate) fn model_member_ini_name(member: &str) -> &str { + let trimmed = member.trim_end_matches(|c: char| c.is_ascii_digit()); + if trimmed.is_empty() { + member + } else { + trimmed + } +} + +pub(crate) fn model_member_matches(member: &str, value: &str) -> bool { + member.eq_ignore_ascii_case(value) || model_member_ini_name(member).eq_ignore_ascii_case(value) +} + +/// Models referenced by W3D-model-typed fields visible from `scope_node`: +/// the scope's own subtree first, then — because a `ConditionState` inherits +/// its model from `DefaultConditionState` when it sets none (see the engine's +/// `W3DModelDraw`) — each enclosing scope's subtree, stopping at the nearest +/// one that declares any model. The climb never crosses the top-level block, +/// so per-root cached diagnostics stay independent of sibling blocks. +pub(crate) fn models_in_scope(analyzer: &Analyzer, scope_node: &SyntaxNode) -> Vec { + let mut out = Vec::new(); + let mut node = scope_node.clone(); + loop { + collect_models(analyzer, &node, &mut out); + if !out.is_empty() { + return out; + } + match node + .parent() + .filter(|p| matches!(p.kind(), SyntaxKind::BLOCK | SyntaxKind::MODULE)) + { + Some(parent) => node = parent, + None => return out, + } + } +} + +fn collect_models(analyzer: &Analyzer, node: &SyntaxNode, out: &mut Vec) { + let scope = scope_schema(analyzer, node); + for child in node.children() { + match child.kind() { + SyntaxKind::FIELD => { + let field = AstField(child); + let Some(schema_field) = field.key().and_then(|key| scope.field(key.text())) else { + continue; + }; + let values = field.value_tokens(); + match &schema_field.value_type { + ValueType::TokenList { tokens } => { + for (spec, value) in tokens.iter().zip(values.iter()) { + if is_model_asset_type(spec) { + out.push(value.text().trim_matches('"').to_string()); + } + } + } + ty if is_model_asset_type(ty) => { + if let Some(value) = values.first() { + out.push(value.text().trim_matches('"').to_string()); + } + } + _ => {} + } + } + SyntaxKind::MODULE | SyntaxKind::BLOCK => collect_models(analyzer, &child, out), + _ => {} + } + } +} diff --git a/crates/analysis/src/nav.rs b/crates/analysis/src/nav.rs index c0b47be..f71d177 100644 --- a/crates/analysis/src/nav.rs +++ b/crates/analysis/src/nav.rs @@ -53,20 +53,60 @@ pub fn reference_at(analyzer: &Analyzer, parse: &Parse, offset: u32) -> Option *ref_kind, ValueType::ReferenceList { ref_kind } => *ref_kind, ValueType::TokenList { tokens } => match tokens.get(pos)? { ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } => *ref_kind, + ValueType::Prefixed { value_type, .. } => match value_type.as_ref() { + ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } => { + *ref_kind + } + _ => return None, + }, _ => return None, }, _ => return None, }; - let name = tok.text().trim_matches('"').to_string(); + let (name, span) = if let ValueType::TokenList { tokens } = active_type { + match tokens.get(pos) { + Some(ValueType::Prefixed { prefix, .. }) => { + let text = tok.text().trim_matches('"'); + let (actual, name) = text.split_once(':')?; + if !actual.eq_ignore_ascii_case(prefix) { + return None; + } + let start = u32::from(tok.text_range().start()) + + u32::from(tok.text().starts_with('"')) + + actual.len() as u32 + + 1; + ( + name.to_string(), + crate::Span { + start, + end: start + name.len() as u32, + }, + ) + } + _ => ( + tok.text().trim_matches('"').to_string(), + tok.text_range().into(), + ), + } + } else { + ( + tok.text().trim_matches('"').to_string(), + tok.text_range().into(), + ) + }; Some(ReferenceAt { kind: ref_kind, name, - span: tok.text_range().into(), + span, }) } @@ -147,4 +187,18 @@ mod tests { _ => panic!("expected field hover"), } } + + #[test] + fn quoted_prefixed_reference_span_excludes_quotes_and_prefix() { + let a = Analyzer::embedded(); + let src = "Object Tank\n Behavior = TransitionDamageFX ModuleTag_01\n DamagedParticleSystem1 = Bone:NONE RandomBone:No \"PSys:MissingParticle\"\n End\nEnd\n"; + let offset = src.find("MissingParticle").unwrap() as u32; + let reference = reference_at(&a, &a.parse(src), offset).unwrap(); + assert_eq!(reference.kind, RefKind::ParticleSystem); + assert_eq!(reference.name, "MissingParticle"); + assert_eq!( + &src[reference.span.start as usize..reference.span.end as usize], + "MissingParticle" + ); + } } diff --git a/crates/analysis/src/semantic.rs b/crates/analysis/src/semantic.rs index e486918..26e1c48 100644 --- a/crates/analysis/src/semantic.rs +++ b/crates/analysis/src/semantic.rs @@ -178,12 +178,13 @@ impl<'a> Sem<'a> { .key() .and_then(|k| scope.field(k.text())) .map(|f| f.value_type.clone()); - for (i, tok) in field.value_tokens().iter().enumerate() { + let value_tokens = field.value_tokens(); + let active_ty = ty.as_ref().and_then(|ty| { + ty.variant_for_first_token(value_tokens.first().map(|t| t.text().trim_matches('"'))) + }); + for (i, tok) in value_tokens.iter().enumerate() { // Token lists classify each position by its own element type. - let elem = match &ty { - Some(ValueType::TokenList { tokens }) => tokens.get(i), - other => other.as_ref(), - }; + let elem = active_ty.and_then(|ty| ty.token_type_at(i)); self.set(tok, value_token_kind(tok, elem)); } } @@ -210,6 +211,11 @@ fn value_token_kind(tok: &SyntaxToken, ty: Option<&ValueType>) -> SemKind { Some(ValueType::Bool) | Some(ValueType::Enum { .. }) | Some(ValueType::BitFlags { .. }) => { SemKind::EnumMember } + Some(ValueType::OneOf { variants }) => variants + .first() + .map(|variant| value_token_kind(tok, Some(variant))) + .unwrap_or(SemKind::StringLit), + Some(ValueType::Prefixed { value_type, .. }) => value_token_kind(tok, Some(value_type)), Some(ValueType::Int) | Some(ValueType::UInt) | Some(ValueType::Real) @@ -222,9 +228,10 @@ fn value_token_kind(tok: &SyntaxToken, ty: Option<&ValueType>) -> SemKind { | Some(ValueType::Color) | Some(ValueType::Coord2D) | Some(ValueType::Coord3D) => SemKind::Number, - Some(ValueType::Reference { .. }) | Some(ValueType::ReferenceList { .. }) => { - SemKind::Reference - } + Some(ValueType::Reference { .. }) + | Some(ValueType::ReferenceList { .. }) + | Some(ValueType::W3dModel) + | Some(ValueType::W3dModelMember) => SemKind::Reference, _ => SemKind::StringLit, } } diff --git a/crates/analysis/tests/spec/AIDataSubblocks.ini b/crates/analysis/tests/spec/AIDataSubblocks.ini index 70737a3..b7d70ee 100644 --- a/crates/analysis/tests/spec/AIDataSubblocks.ini +++ b/crates/analysis/tests/spec/AIDataSubblocks.ini @@ -28,5 +28,9 @@ AIData AutomaticallyBuild = No $5 End + Structure AIDataSpecBuilding + End + Structure MissingAIDataStructure + End End End diff --git a/crates/analysis/tests/spec/AIDataSubblocks.spec.toml b/crates/analysis/tests/spec/AIDataSubblocks.spec.toml index 6224ac4..609e773 100644 --- a/crates/analysis/tests/spec/AIDataSubblocks.spec.toml +++ b/crates/analysis/tests/spec/AIDataSubblocks.spec.toml @@ -18,6 +18,17 @@ code = "unknown-field" on = "Location" absent = true +[[diag]] +severity = "warning" +code = "unresolved-reference" +on = "AIDataSpecBuilding" +absent = true + +[[diag]] +severity = "warning" +code = "unresolved-reference" +on = "MissingAIDataStructure" + [[complete]] at = "$1" includes = ["ResourceGatherersEasy", "BaseDefenseStructure1", "SkillSet1"] diff --git a/crates/analysis/tests/spec/AIUpdateValues.ini b/crates/analysis/tests/spec/AIUpdateValues.ini new file mode 100644 index 0000000..c6bac80 --- /dev/null +++ b/crates/analysis/tests/spec/AIUpdateValues.ini @@ -0,0 +1,12 @@ +Object AIUpdateValues + Behavior = AIUpdateInterface ModuleTag_04 + ForbidPlayerCommands = Yes + MoodAttackCheckRate = 10 + SurrenderDuration = 1 + TurretsLinked = Yes + Turret + ControlledWeaponSlots = PRIMARY SECONDARY $1TERTIARY + End + AutoAcquireEnemiesWhenIdle = YES STEALTHED $2NO + End +End diff --git a/crates/analysis/tests/spec/AIUpdateValues.spec.toml b/crates/analysis/tests/spec/AIUpdateValues.spec.toml new file mode 100644 index 0000000..def670c --- /dev/null +++ b/crates/analysis/tests/spec/AIUpdateValues.spec.toml @@ -0,0 +1,9 @@ +no_errors = true + +[[complete]] +at = "$1" +includes = ["PRIMARY", "SECONDARY", "TERTIARY"] + +[[complete]] +at = "$2" +includes = ["YES", "STEALTHED", "NO", "NOTWHILEATTACKING", "ATTACK_BUILDINGS"] diff --git a/crates/analysis/tests/spec/AutoChooseSources.ini b/crates/analysis/tests/spec/AutoChooseSources.ini new file mode 100644 index 0000000..a5d2c08 --- /dev/null +++ b/crates/analysis/tests/spec/AutoChooseSources.ini @@ -0,0 +1,17 @@ +Object AutoChooseSourcesTest + WeaponSet + Conditions = NONE + Weapon = PRIMARY MissileDefenderMissileWeapon + Weapon = SECONDARY MissileDefenderLaserGuidedMissileWeapon ; Controlled by special ability + AutoChooseSources = PRIMARY FROM_PLAYER FROM_SCRIPT FROM_AI + AutoChooseSources = SECONDARY FROM_PLAYER $1NONE + End +End + +Weapon MissileDefenderMissileWeapon + PrimaryDamage = 10 +End + +Weapon MissileDefenderLaserGuidedMissileWeapon + PrimaryDamage = 10 +End diff --git a/crates/analysis/tests/spec/AutoChooseSources.spec.toml b/crates/analysis/tests/spec/AutoChooseSources.spec.toml new file mode 100644 index 0000000..11ee089 --- /dev/null +++ b/crates/analysis/tests/spec/AutoChooseSources.spec.toml @@ -0,0 +1,6 @@ +no_errors = true + +# `AutoChooseSources` consumes a weapon slot followed by CommandSource flags. +[[complete]] +at = "$1" +includes = ["FROM_PLAYER", "FROM_SCRIPT", "FROM_AI", "FROM_DOZER", "DEFAULT_SWITCH_WEAPON"] diff --git a/crates/analysis/tests/spec/AutoChooseSourcesInvalid.ini b/crates/analysis/tests/spec/AutoChooseSourcesInvalid.ini new file mode 100644 index 0000000..3801ea0 --- /dev/null +++ b/crates/analysis/tests/spec/AutoChooseSourcesInvalid.ini @@ -0,0 +1,6 @@ +Object AutoChooseSourcesInvalid + WeaponSet + Conditions = NONE + AutoChooseSources = TERTIARY BAD_SOURCE + End +End diff --git a/crates/analysis/tests/spec/AutoChooseSourcesInvalid.spec.toml b/crates/analysis/tests/spec/AutoChooseSourcesInvalid.spec.toml new file mode 100644 index 0000000..92b1052 --- /dev/null +++ b/crates/analysis/tests/spec/AutoChooseSourcesInvalid.spec.toml @@ -0,0 +1,4 @@ +[[diag]] +severity = "error" +code = "bad-flag" +on = "BAD_SOURCE" diff --git a/crates/analysis/tests/spec/ChallengeGenerals.ini b/crates/analysis/tests/spec/ChallengeGenerals.ini new file mode 100644 index 0000000..25ee3ec --- /dev/null +++ b/crates/analysis/tests/spec/ChallengeGenerals.ini @@ -0,0 +1,9 @@ +ChallengeGenerals + GeneralPersona0 + StartsEnabled = YES + BioPortraitSmall = PAAirGen_S + PlayerTemplate = FactionAmericaAirForceGeneral + TauntSound1 = Taunts_Grainger061 + $1 + End +End diff --git a/crates/analysis/tests/spec/ChallengeGenerals.spec.toml b/crates/analysis/tests/spec/ChallengeGenerals.spec.toml new file mode 100644 index 0000000..0c782a4 --- /dev/null +++ b/crates/analysis/tests/spec/ChallengeGenerals.spec.toml @@ -0,0 +1,30 @@ +no_errors = true + +[[diag]] +severity = "warning" +code = "unknown-field" +on = "StartsEnabled" +absent = true + +[[diag]] +severity = "warning" +code = "unknown-field" +on = "BioPortraitSmall" +absent = true + +[[diag]] +severity = "warning" +code = "unknown-field" +on = "PlayerTemplate" +absent = true + +[[diag]] +severity = "warning" +code = "unknown-field" +on = "TauntSound1" +absent = true + +[[complete]] +at = "$1" +includes = ["StartsEnabled", "BioNameString", "BioPortraitSmall", "PlayerTemplate", "TauntSound1", "NameSound"] +excludes = ["GeneralPersona1"] diff --git a/crates/analysis/tests/spec/ReferenceTest.ini b/crates/analysis/tests/spec/ReferenceTest.ini index 4c3ec56..61ae03c 100644 --- a/crates/analysis/tests/spec/ReferenceTest.ini +++ b/crates/analysis/tests/spec/ReferenceTest.ini @@ -20,6 +20,15 @@ End Object RefTestObject ButtonImage = $1 SelectPortrait = NoSuchImage + Behavior = RiderChangeContain ModuleTag_Riders + Rider1 = $5 RIDER1 WEAPON_RIDER1 STATUS_RIDER1 RefTestCommandSet SET_NORMAL + Rider2 = RefTestObject $6 WEAPON_RIDER1 STATUS_RIDER1 RefTestCommandSet SET_NORMAL + Rider3 = RefTestObject RIDER1 $7 STATUS_RIDER1 RefTestCommandSet SET_NORMAL + Rider4 = RefTestObject RIDER1 WEAPON_RIDER1 $8 RefTestCommandSet SET_NORMAL + Rider5 = RefTestObject RIDER1 WEAPON_RIDER1 STATUS_RIDER1 $9 SET_NORMAL + Rider6 = RefTestObject RIDER1 WEAPON_RIDER1 STATUS_RIDER1 RefTestCommandSet $10 + Rider7 = NoSuchRiderObject RIDER1 WEAPON_RIDER1 STATUS_RIDER1 NoSuchCommandSet SET_NORMAL + End End Weapon RefTestWeapon diff --git a/crates/analysis/tests/spec/ReferenceTest.spec.toml b/crates/analysis/tests/spec/ReferenceTest.spec.toml index 9fd717c..20c18bd 100644 --- a/crates/analysis/tests/spec/ReferenceTest.spec.toml +++ b/crates/analysis/tests/spec/ReferenceTest.spec.toml @@ -9,6 +9,17 @@ severity = "warning" code = "unresolved-reference" on = "NoSuchImage" +# Rider fields are positional token lists: object and command-set tokens are references. +[[diag]] +severity = "warning" +code = "unresolved-reference" +on = "NoSuchRiderObject" + +[[diag]] +severity = "warning" +code = "unresolved-reference" +on = "NoSuchCommandSet" + # `ButtonImage =` offers the workspace's mapped images. [[complete]] at = "$1" @@ -28,3 +39,28 @@ includes = ["TestFireSound"] [[complete]] at = "$4" includes = ["Command_RefTest"] + +# Rider1 value positions complete by their typed token. +[[complete]] +at = "$5" +includes = ["RefTestObject"] + +[[complete]] +at = "$6" +includes = ["RIDER1"] + +[[complete]] +at = "$7" +includes = ["WEAPON_RIDER1"] + +[[complete]] +at = "$8" +includes = ["STATUS_RIDER1"] + +[[complete]] +at = "$9" +includes = ["RefTestCommandSet"] + +[[complete]] +at = "$10" +includes = ["SET_NORMAL"] diff --git a/crates/analysis/tests/spec/SpecialAbilityUpdateInvalidReference.ini b/crates/analysis/tests/spec/SpecialAbilityUpdateInvalidReference.ini new file mode 100644 index 0000000..731dfad --- /dev/null +++ b/crates/analysis/tests/spec/SpecialAbilityUpdateInvalidReference.ini @@ -0,0 +1,5 @@ +Object SpecialAbilityInvalidReferenceTest + Behavior = SpecialAbilityUpdate ModuleTag_09 + SpecialObject = MissingSpecialObject + End +End diff --git a/crates/analysis/tests/spec/SpecialAbilityUpdateInvalidReference.spec.toml b/crates/analysis/tests/spec/SpecialAbilityUpdateInvalidReference.spec.toml new file mode 100644 index 0000000..cb3f1c1 --- /dev/null +++ b/crates/analysis/tests/spec/SpecialAbilityUpdateInvalidReference.spec.toml @@ -0,0 +1,4 @@ +[[diag]] +severity = "warning" +code = "unresolved-reference" +on = "MissingSpecialObject" diff --git a/crates/analysis/tests/spec/SpecialAbilityUpdateReferences.ini b/crates/analysis/tests/spec/SpecialAbilityUpdateReferences.ini new file mode 100644 index 0000000..8ea38b7 --- /dev/null +++ b/crates/analysis/tests/spec/SpecialAbilityUpdateReferences.ini @@ -0,0 +1,17 @@ +SpecialPower SpecialAbilityMissileDefenderLaserGuidedMissiles +End + +Object LaserBeam +End + +Object SpecialAbilityReferenceTest + Behavior = SpecialAbilityUpdate ModuleTag_09 + SpecialPowerTemplate = SpecialAbilityMissileDefenderLaserGuidedMissiles + StartAbilityRange = 200.0 + AbilityAbortRange = 250.0 + PreparationTime = 1000 + SpecialObject = $1 + SpecialObjectAttachToBone = Muzzle01 + PersistentPrepTime = 500 + End +End diff --git a/crates/analysis/tests/spec/SpecialAbilityUpdateReferences.spec.toml b/crates/analysis/tests/spec/SpecialAbilityUpdateReferences.spec.toml new file mode 100644 index 0000000..a8502e3 --- /dev/null +++ b/crates/analysis/tests/spec/SpecialAbilityUpdateReferences.spec.toml @@ -0,0 +1,5 @@ +no_errors = true + +[[complete]] +at = "$1" +includes = ["LaserBeam"] diff --git a/crates/schema/schema.json b/crates/schema/schema.json index cd233f3..5c66308 100644 --- a/crates/schema/schema.json +++ b/crates/schema/schema.json @@ -1402,40 +1402,2404 @@ "fields": [], "sub_blocks": [ { - "keyword": "GeneralPersona0" + "keyword": "GeneralPersona0", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona1" + "keyword": "GeneralPersona1", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona2" + "keyword": "GeneralPersona2", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona3" + "keyword": "GeneralPersona3", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona4" + "keyword": "GeneralPersona4", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona5" + "keyword": "GeneralPersona5", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona6" + "keyword": "GeneralPersona6", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona7" + "keyword": "GeneralPersona7", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona8" + "keyword": "GeneralPersona8", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona9" + "keyword": "GeneralPersona9", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona10" + "keyword": "GeneralPersona10", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] }, { - "keyword": "GeneralPersona11" + "keyword": "GeneralPersona11", + "fields": [ + { + "name": "StartsEnabled", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool" + }, + { + "name": "BioNameString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioDOBString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBirthplaceString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioStrategyString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioRankString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioBranchString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioClassNumberString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "BioPortraitSmall", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "BioPortraitLarge", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "Campaign", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PlayerTemplate", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieLeftName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PortraitMovieRightName", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "DefeatedImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "VictoriousImage", + "value_type": { + "kind": "reference", + "ref_kind": "mapped_image" + }, + "parse_fn": "INI::parseMappedImage" + }, + { + "name": "DefeatedString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "VictoriousString", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "SelectionSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound1", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound2", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "TauntSound3", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "WinSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "LossSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "PreviewSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + }, + { + "name": "NameSound", + "value_type": { + "kind": "reference", + "ref_kind": "audio_event" + }, + "parse_fn": "INI::parseAsciiString" + } + ] } ] }, @@ -1449,8 +3813,8 @@ { "name": "Command", "value_type": { - "kind": "unknown", - "parse_fn": "CommandButton::parseCommand" + "kind": "enum", + "value_set": "command_button_command" }, "parse_fn": "CommandButton::parseCommand", "doc": null @@ -1458,8 +3822,8 @@ { "name": "Options", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "command_button_options" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -1577,8 +3941,8 @@ { "name": "ButtonBorderType", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "command_button_border_type" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -2463,7 +4827,7 @@ "name": "CrateData", "parse_fn": "INI::parseCrateTemplateDefinition", "named": true, - "defines": null, + "defines": "crate_data", "doc": null, "fields": [ { @@ -3119,7 +5483,7 @@ "name": "EvaEvent", "parse_fn": "INI::parseEvaEvent", "named": true, - "defines": null, + "defines": "eva_event", "doc": null, "fields": [ { @@ -7462,11 +9826,11 @@ { "name": "Surfaces", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "locomotor_surface" }, "parse_fn": "INI::parseBitString32", - "doc": "Surface-type flags (set not yet enumerated)." + "doc": "Surface-type flags." }, { "name": "Speed", @@ -10058,8 +12422,17 @@ { "name": "AutoChooseSources", "value_type": { - "kind": "unknown", - "parse_fn": "WeaponTemplateSet::parseAutoChoose" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "bit_flags", + "value_set": "command_source" + } + ] }, "parse_fn": "WeaponTemplateSet::parseAutoChoose", "doc": null @@ -13080,7 +15453,8 @@ { "name": "ButtonImage", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "mapped_image" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -14264,8 +16638,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -14328,7 +16702,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -14336,7 +16710,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14352,7 +16726,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14368,7 +16742,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14384,7 +16758,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14400,7 +16774,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -14408,7 +16782,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -14416,7 +16790,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14424,7 +16807,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14432,7 +16824,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14440,7 +16841,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14448,7 +16858,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14506,8 +16925,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -14515,8 +16942,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -14533,7 +16967,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -14541,7 +16975,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14557,7 +16991,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14573,7 +17007,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14589,7 +17023,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14605,7 +17039,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -14613,7 +17047,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -14621,7 +17055,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14629,7 +17072,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14637,7 +17089,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14645,7 +17106,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14653,7 +17123,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14711,8 +17190,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -14720,8 +17207,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -14741,7 +17235,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -14749,7 +17243,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14765,7 +17259,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14781,7 +17275,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14797,7 +17291,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -14813,7 +17307,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -14821,7 +17315,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -14829,7 +17323,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14837,7 +17340,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14845,7 +17357,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14853,7 +17374,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14861,7 +17391,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -14919,8 +17458,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -14928,8 +17475,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -15037,7 +17591,8 @@ { "name": "FXListUpgrade", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "fx_list" }, "parse_fn": "INI::parseFXList", "doc": null @@ -15050,29 +17605,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -15173,8 +17710,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -15182,8 +17727,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -15191,8 +17744,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -15335,8 +17888,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -15344,8 +17905,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -15353,8 +17922,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -15533,29 +18102,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -15672,8 +18223,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -15681,8 +18240,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -15690,8 +18257,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -15834,8 +18401,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -15843,8 +18418,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -15852,8 +18435,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -15954,8 +18537,8 @@ { "name": "AssistingWeaponSlot", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -15963,7 +18546,8 @@ { "name": "LaserFromAssisted", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -15971,7 +18555,8 @@ { "name": "LaserToTarget", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16021,8 +18606,24 @@ { "name": "UpgradedBoost", "value_type": { - "kind": "unknown", - "parse_fn": "parseUpgradePair" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "UpgradeType", + "value_type": { + "kind": "reference", + "ref_kind": "upgrade" + } + }, + { + "kind": "prefixed", + "prefix": "Boost", + "value_type": { + "kind": "int" + } + } + ] }, "parse_fn": "parseUpgradePair", "doc": null @@ -16278,7 +18879,8 @@ { "name": "DetonationObject", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16376,7 +18978,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "fx_list" } ] @@ -16394,7 +18996,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "object_creation_list" } ] @@ -16405,8 +19007,17 @@ { "name": "Weapon", "value_type": { - "kind": "unknown", - "parse_fn": "parseWeapon" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "slow_death_phase" + }, + { + "kind": "reference_list", + "ref_kind": "weapon" + } + ] }, "parse_fn": "parseWeapon", "doc": null @@ -16593,7 +19204,8 @@ { "name": "BombardmentPlanUnpackSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16601,7 +19213,8 @@ { "name": "BombardmentPlanPackSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16617,7 +19230,8 @@ { "name": "BombardmentAnnouncementName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16625,7 +19239,8 @@ { "name": "SearchAndDestroyPlanUnpackSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16633,7 +19248,8 @@ { "name": "SearchAndDestroyPlanIdleLoopSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16641,7 +19257,8 @@ { "name": "SearchAndDestroyPlanPackSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16657,7 +19274,8 @@ { "name": "SearchAndDestroyAnnouncementName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16665,7 +19283,8 @@ { "name": "HoldTheLinePlanUnpackSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16673,7 +19292,8 @@ { "name": "HoldTheLinePlanPackSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16689,7 +19309,8 @@ { "name": "HoldTheLineAnnouncementName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16772,7 +19393,8 @@ { "name": "VisionObjectName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -16812,17 +19434,7 @@ "interfaces": [ "Damage" ], - "fields": [ - { - "name": "DamageTypes", - "value_type": { - "kind": "bit_flags", - "value_set": "damage_type" - }, - "parse_fn": "INI::parseDamageTypeFlags", - "doc": null - } - ], + "fields": [], "sub_blocks": [], "doc": null }, @@ -16862,8 +19474,37 @@ { "name": "PristineFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16871,8 +19512,37 @@ { "name": "PristineFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16880,8 +19550,37 @@ { "name": "PristineFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16889,8 +19588,37 @@ { "name": "PristineFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16898,8 +19626,37 @@ { "name": "PristineFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16907,8 +19664,37 @@ { "name": "PristineFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16916,8 +19702,37 @@ { "name": "PristineFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16925,8 +19740,37 @@ { "name": "PristineFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16934,8 +19778,37 @@ { "name": "DamagedFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16943,8 +19816,37 @@ { "name": "DamagedFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16952,8 +19854,37 @@ { "name": "DamagedFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16961,8 +19892,37 @@ { "name": "DamagedFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16970,8 +19930,37 @@ { "name": "DamagedFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16979,8 +19968,37 @@ { "name": "DamagedFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16988,8 +20006,37 @@ { "name": "DamagedFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -16997,8 +20044,37 @@ { "name": "DamagedFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17006,8 +20082,37 @@ { "name": "ReallyDamagedFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17015,8 +20120,37 @@ { "name": "ReallyDamagedFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17024,8 +20158,37 @@ { "name": "ReallyDamagedFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17033,8 +20196,37 @@ { "name": "ReallyDamagedFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17042,8 +20234,37 @@ { "name": "ReallyDamagedFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17051,8 +20272,37 @@ { "name": "ReallyDamagedFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17060,8 +20310,37 @@ { "name": "ReallyDamagedFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17069,8 +20348,37 @@ { "name": "ReallyDamagedFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17078,8 +20386,37 @@ { "name": "RubbleFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17087,8 +20424,37 @@ { "name": "RubbleFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17096,8 +20462,37 @@ { "name": "RubbleFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17105,8 +20500,37 @@ { "name": "RubbleFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17114,8 +20538,37 @@ { "name": "RubbleFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17123,8 +20576,37 @@ { "name": "RubbleFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17132,8 +20614,37 @@ { "name": "RubbleFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17141,8 +20652,37 @@ { "name": "RubbleFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseFXList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseFXList", "doc": null @@ -17150,8 +20690,37 @@ { "name": "PristineOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17159,8 +20728,37 @@ { "name": "PristineOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17168,8 +20766,37 @@ { "name": "PristineOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17177,8 +20804,37 @@ { "name": "PristineOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17186,8 +20842,37 @@ { "name": "PristineOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17195,8 +20880,37 @@ { "name": "PristineOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17204,8 +20918,37 @@ { "name": "PristineOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17213,8 +20956,37 @@ { "name": "PristineOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17222,8 +20994,37 @@ { "name": "DamagedOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17231,8 +21032,37 @@ { "name": "DamagedOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17240,8 +21070,37 @@ { "name": "DamagedOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17249,8 +21108,37 @@ { "name": "DamagedOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17258,8 +21146,37 @@ { "name": "DamagedOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17267,8 +21184,37 @@ { "name": "DamagedOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17276,8 +21222,37 @@ { "name": "DamagedOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17285,8 +21260,37 @@ { "name": "DamagedOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17294,8 +21298,37 @@ { "name": "ReallyDamagedOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17303,8 +21336,37 @@ { "name": "ReallyDamagedOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17312,8 +21374,37 @@ { "name": "ReallyDamagedOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17321,8 +21412,37 @@ { "name": "ReallyDamagedOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17330,8 +21450,37 @@ { "name": "ReallyDamagedOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17339,8 +21488,37 @@ { "name": "ReallyDamagedOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17348,8 +21526,37 @@ { "name": "ReallyDamagedOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17357,8 +21564,37 @@ { "name": "ReallyDamagedOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17366,8 +21602,37 @@ { "name": "RubbleOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17375,8 +21640,37 @@ { "name": "RubbleOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17384,8 +21678,37 @@ { "name": "RubbleOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17393,8 +21716,37 @@ { "name": "RubbleOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17402,8 +21754,37 @@ { "name": "RubbleOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17411,8 +21792,37 @@ { "name": "RubbleOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17420,8 +21830,37 @@ { "name": "RubbleOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17429,8 +21868,37 @@ { "name": "RubbleOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseObjectCreationList", "doc": null @@ -17438,8 +21906,37 @@ { "name": "PristineParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17447,8 +21944,37 @@ { "name": "PristineParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17456,8 +21982,37 @@ { "name": "PristineParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17465,8 +22020,37 @@ { "name": "PristineParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17474,8 +22058,37 @@ { "name": "PristineParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17483,8 +22096,37 @@ { "name": "PristineParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17492,8 +22134,37 @@ { "name": "PristineParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17501,8 +22172,37 @@ { "name": "PristineParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17510,8 +22210,37 @@ { "name": "DamagedParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17519,8 +22248,37 @@ { "name": "DamagedParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17528,8 +22286,37 @@ { "name": "DamagedParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17537,8 +22324,37 @@ { "name": "DamagedParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17546,8 +22362,37 @@ { "name": "DamagedParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17555,8 +22400,37 @@ { "name": "DamagedParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17564,8 +22438,37 @@ { "name": "DamagedParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17573,8 +22476,37 @@ { "name": "DamagedParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17582,8 +22514,37 @@ { "name": "ReallyDamagedParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17591,8 +22552,37 @@ { "name": "ReallyDamagedParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17600,8 +22590,37 @@ { "name": "ReallyDamagedParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17609,8 +22628,37 @@ { "name": "ReallyDamagedParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17618,8 +22666,37 @@ { "name": "ReallyDamagedParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17627,8 +22704,37 @@ { "name": "ReallyDamagedParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17636,8 +22742,37 @@ { "name": "ReallyDamagedParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17645,8 +22780,37 @@ { "name": "ReallyDamagedParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17654,8 +22818,37 @@ { "name": "RubbleParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17663,8 +22856,37 @@ { "name": "RubbleParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17672,8 +22894,37 @@ { "name": "RubbleParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17681,8 +22932,37 @@ { "name": "RubbleParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17690,8 +22970,37 @@ { "name": "RubbleParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17699,8 +23008,37 @@ { "name": "RubbleParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17708,8 +23046,37 @@ { "name": "RubbleParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17717,8 +23084,37 @@ { "name": "RubbleParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + }, + { + "kind": "prefixed", + "prefix": "OnlyOnce", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "duration" + }, + { + "kind": "duration" + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] }, "parse_fn": "BoneFXUpdateModuleData::parseParticleSystem", "doc": null @@ -17752,8 +23148,31 @@ { "name": "BridgeDieFX", "value_type": { - "kind": "unknown", - "parse_fn": "parseFX" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "FX", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + }, + { + "kind": "prefixed", + "prefix": "Delay", + "value_type": { + "kind": "duration" + } + }, + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + } + ] }, "parse_fn": "parseFX", "doc": null @@ -17761,8 +23180,31 @@ { "name": "BridgeDieOCL", "value_type": { - "kind": "unknown", - "parse_fn": "parseOCL" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + }, + { + "kind": "prefixed", + "prefix": "Delay", + "value_type": { + "kind": "duration" + } + }, + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "w3d_model_member" + } + } + ] }, "parse_fn": "parseOCL", "doc": null @@ -17798,7 +23240,8 @@ { "name": "UpgradeRequired", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "upgrade" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -17918,8 +23361,16 @@ { "name": "UpgradeBounty", "value_type": { - "kind": "unknown", - "parse_fn": "parseBountyUpgradePair" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "science" + }, + { + "kind": "percent" + } + ] }, "parse_fn": "parseBountyUpgradePair", "doc": null @@ -17987,8 +23438,16 @@ { "name": "UpgradeMoneyAmount", "value_type": { - "kind": "unknown", - "parse_fn": "parseCashHackUpgradePair" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "science" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseCashHackUpgradePair", "doc": null @@ -18207,29 +23666,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -18326,7 +23767,8 @@ { "name": "RopeName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -18422,7 +23864,8 @@ { "name": "RotorWashParticleSystem", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -18499,8 +23942,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -18508,8 +23959,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -18517,8 +23976,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -18661,8 +24120,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -18670,8 +24137,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -18679,8 +24154,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -18833,8 +24308,8 @@ { "name": "WeaponSlot", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -18894,7 +24369,8 @@ { "name": "CommandSet", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "command_set" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -18902,7 +24378,8 @@ { "name": "CommandSetAlt", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "command_set" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -18910,7 +24387,8 @@ { "name": "TriggerAlt", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "upgrade" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -19040,7 +24518,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -19159,7 +24638,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -19272,7 +24752,8 @@ { "name": "FlareTemplateName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -19422,8 +24903,8 @@ { "name": "CrateData", "value_type": { - "kind": "unknown", - "parse_fn": "CreateCrateDieModuleData::parseCrateData" + "kind": "reference", + "ref_kind": "crate_data" }, "parse_fn": "CreateCrateDieModuleData::parseCrateData", "doc": null @@ -19808,29 +25289,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -19878,7 +25341,8 @@ { "name": "PutInContainer", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -19923,15 +25387,6 @@ "parse_fn": "INI::parseCoord3D", "doc": null }, - { - "name": "DeliveryDecal", - "value_type": { - "kind": "unknown", - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate" - }, - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate", - "doc": null - }, { "name": "DeliveryDecalRadius", "value_type": { @@ -19942,6 +25397,70 @@ } ], "sub_blocks": [ + { + "keyword": "DeliveryDecal", + "fields": [ + { + "name": "Texture", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString", + "doc": null + }, + { + "name": "Style", + "value_type": { + "kind": "bit_flags", + "value_set": "shadow_type" + }, + "parse_fn": "INI::parseBitString32", + "doc": null + }, + { + "name": "OpacityMin", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityMax", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityThrobTime", + "value_type": { + "kind": "duration" + }, + "parse_fn": "INI::parseDurationUnsignedInt", + "doc": null + }, + { + "name": "Color", + "value_type": { + "kind": "color" + }, + "parse_fn": "INI::parseColorInt", + "doc": null + }, + { + "name": "OnlyVisibleToOwningPlayer", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + } + ], + "sub_blocks": [], + "doc": "RadiusDecalTemplate nested field table." + }, { "keyword": "Turret", "fields": [ @@ -20004,8 +25523,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -20013,8 +25540,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -20022,8 +25557,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -20166,8 +25701,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -20175,8 +25718,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -20184,8 +25735,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -20286,8 +25837,8 @@ { "name": "DetonationWeaponSlot", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -20295,8 +25846,8 @@ { "name": "ProximityModeWeaponSlot", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -20304,8 +25855,8 @@ { "name": "ManualModeWeaponSlot", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -20479,29 +26030,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -20650,8 +26183,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -20659,8 +26200,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -20668,8 +26217,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -20812,8 +26361,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -20821,8 +26378,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -20830,8 +26395,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -20967,29 +26532,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -21114,8 +26661,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -21123,8 +26678,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -21132,8 +26695,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -21276,8 +26839,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -21285,8 +26856,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -21294,8 +26873,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -21639,18 +27218,74 @@ }, "parse_fn": "INI::parseReal", "doc": null - }, + } + ], + "sub_blocks": [ { - "name": "GridDecalTemplate", - "value_type": { - "kind": "unknown", - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate" - }, - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate", - "doc": null + "keyword": "GridDecalTemplate", + "fields": [ + { + "name": "Texture", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString", + "doc": null + }, + { + "name": "Style", + "value_type": { + "kind": "bit_flags", + "value_set": "shadow_type" + }, + "parse_fn": "INI::parseBitString32", + "doc": null + }, + { + "name": "OpacityMin", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityMax", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityThrobTime", + "value_type": { + "kind": "duration" + }, + "parse_fn": "INI::parseDurationUnsignedInt", + "doc": null + }, + { + "name": "Color", + "value_type": { + "kind": "color" + }, + "parse_fn": "INI::parseColorInt", + "doc": null + }, + { + "name": "OnlyVisibleToOwningPlayer", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + } + ], + "sub_blocks": [], + "doc": "RadiusDecalTemplate nested field table." } ], - "sub_blocks": [], "doc": null }, { @@ -21691,14 +27326,6 @@ "parse_fn": "INI::parseDurationUnsignedInt", "doc": null }, - { - "name": "SpinRateMax", - "value_type": { - "kind": "real" - }, - "parse_fn": "INI::parseReal", - "doc": null - }, { "name": "TargetScaleMax", "value_type": { @@ -21759,8 +27386,8 @@ { "name": "DoesNotAffect", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_affects" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -22071,8 +27698,8 @@ { "name": "WeaponSlot", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -22915,7 +28542,8 @@ { "name": "BurningSoundName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -22946,29 +28574,11 @@ "Behavior" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -23032,8 +28642,7 @@ { "name": "Runway1Takeoff", "value_type": { - "kind": "unknown", - "parse_fn": "parseRunwayStrip" + "kind": "ascii_string_list" }, "parse_fn": "parseRunwayStrip", "doc": null @@ -23041,8 +28650,7 @@ { "name": "Runway1Landing", "value_type": { - "kind": "unknown", - "parse_fn": "parseRunwayStrip" + "kind": "ascii_string_list" }, "parse_fn": "parseRunwayStrip", "doc": null @@ -23083,8 +28691,7 @@ { "name": "Runway2Takeoff", "value_type": { - "kind": "unknown", - "parse_fn": "parseRunwayStrip" + "kind": "ascii_string_list" }, "parse_fn": "parseRunwayStrip", "doc": null @@ -23092,8 +28699,7 @@ { "name": "Runway2Landing", "value_type": { - "kind": "unknown", - "parse_fn": "parseRunwayStrip" + "kind": "ascii_string_list" }, "parse_fn": "parseRunwayStrip", "doc": null @@ -23166,7 +28772,8 @@ { "name": "PayloadTemplate", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -23398,8 +29005,16 @@ { "name": "InitialRoster", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialRoster" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialRoster", "doc": null @@ -23469,7 +29084,8 @@ { "name": "MineName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -23477,7 +29093,8 @@ { "name": "UpgradedMineName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -23636,7 +29253,8 @@ { "name": "GrantScience", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "science" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -23750,7 +29368,8 @@ { "name": "UpgradeToGrant", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "upgrade" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -23774,29 +29393,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -23977,8 +29578,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -23986,8 +29595,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -23995,8 +29612,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -24139,8 +29756,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -24148,8 +29773,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -24157,8 +29790,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -24372,14 +30005,6 @@ "parse_fn": "INI::parseBool", "doc": null }, - { - "name": "TimeForFullHeal", - "value_type": { - "kind": "duration" - }, - "parse_fn": "INI::parseDurationUnsignedInt", - "doc": null - }, { "name": "DeathTypes", "value_type": { @@ -24415,6 +30040,14 @@ }, "parse_fn": "ObjectStatusMaskType::parseFromINI", "doc": null + }, + { + "name": "TimeForFullHeal", + "value_type": { + "kind": "duration" + }, + "parse_fn": "INI::parseDurationUnsignedInt", + "doc": null } ], "sub_blocks": [], @@ -24497,7 +30130,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -24668,7 +30302,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "fx_list" } ] @@ -24686,7 +30320,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "object_creation_list" } ] @@ -24697,8 +30331,17 @@ { "name": "Weapon", "value_type": { - "kind": "unknown", - "parse_fn": "parseWeapon" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "slow_death_phase" + }, + { + "kind": "reference_list", + "ref_kind": "weapon" + } + ] }, "parse_fn": "parseWeapon", "doc": null @@ -24843,7 +30486,8 @@ { "name": "BladeObjectName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -24930,7 +30574,8 @@ { "name": "FinalRubbleObject", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -25197,8 +30842,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -25230,7 +30883,8 @@ { "name": "PayloadTemplateName", "value_type": { - "kind": "ascii_string_list" + "kind": "reference_list", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiStringVectorAppend", "doc": null @@ -25358,7 +31012,8 @@ { "name": "ParachuteName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -25595,8 +31250,8 @@ { "name": "FX", "value_type": { - "kind": "unknown", - "parse_fn": "parseFX" + "kind": "reference_list", + "ref_kind": "fx_list" }, "parse_fn": "parseFX", "doc": null @@ -25604,8 +31259,8 @@ { "name": "OCL", "value_type": { - "kind": "unknown", - "parse_fn": "parseOCL" + "kind": "reference_list", + "ref_kind": "object_creation_list" }, "parse_fn": "parseOCL", "doc": null @@ -25613,8 +31268,8 @@ { "name": "Weapon", "value_type": { - "kind": "unknown", - "parse_fn": "parseWeapon" + "kind": "reference_list", + "ref_kind": "weapon" }, "parse_fn": "parseWeapon", "doc": null @@ -25864,8 +31519,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -25948,29 +31611,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -26116,7 +31761,8 @@ { "name": "LockonCursor", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -26225,8 +31871,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -26234,8 +31888,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -26243,8 +31905,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -26387,8 +32049,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -26396,8 +32066,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -26405,8 +32083,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -26570,7 +32248,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "fx_list" } ] @@ -26588,7 +32266,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "object_creation_list" } ] @@ -26599,8 +32277,17 @@ { "name": "Weapon", "value_type": { - "kind": "unknown", - "parse_fn": "parseWeapon" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "slow_death_phase" + }, + { + "kind": "reference_list", + "ref_kind": "weapon" + } + ] }, "parse_fn": "parseWeapon", "doc": null @@ -26879,7 +32566,8 @@ { "name": "MuzzleParticleSystem", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -26887,7 +32575,8 @@ { "name": "TargetParticleSystem", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -26982,8 +32671,8 @@ { "name": "SlotToLock", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseLookupList" + "kind": "enum", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseLookupList", "doc": null @@ -27135,8 +32824,8 @@ { "name": "DetonatedBy", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "relationship" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -27224,29 +32913,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -27487,8 +33158,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -27496,8 +33175,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -27505,8 +33192,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -27649,8 +33336,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -27658,8 +33353,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -27667,8 +33370,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -28072,8 +33775,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -28135,8 +33846,8 @@ { "name": "ConditionFlag", "value_type": { - "kind": "unknown", - "parse_fn": "ModelConditionFlags::parseSingleBitFromINI" + "kind": "enum", + "value_set": "model_condition" }, "parse_fn": "ModelConditionFlags::parseSingleBitFromINI", "doc": null @@ -28266,7 +33977,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -28306,8 +34018,24 @@ { "name": "UpgradedBoost", "value_type": { - "kind": "unknown", - "parse_fn": "parseUpgradePair" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "UpgradeType", + "value_type": { + "kind": "reference", + "ref_kind": "upgrade" + } + }, + { + "kind": "prefixed", + "prefix": "Boost", + "value_type": { + "kind": "int" + } + } + ] }, "parse_fn": "parseUpgradePair", "doc": null @@ -28430,7 +34158,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "fx_list" } ] @@ -28448,7 +34176,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "object_creation_list" } ] @@ -28459,8 +34187,17 @@ { "name": "Weapon", "value_type": { - "kind": "unknown", - "parse_fn": "parseWeapon" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "slow_death_phase" + }, + { + "kind": "reference_list", + "ref_kind": "weapon" + } + ] }, "parse_fn": "parseWeapon", "doc": null @@ -29298,15 +35035,6 @@ "parse_fn": "INI::parseFXList", "doc": null }, - { - "name": "DeliveryDecal", - "value_type": { - "kind": "unknown", - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate" - }, - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate", - "doc": null - }, { "name": "DeliveryDecalRadius", "value_type": { @@ -29316,7 +35044,72 @@ "doc": null } ], - "sub_blocks": [], + "sub_blocks": [ + { + "keyword": "DeliveryDecal", + "fields": [ + { + "name": "Texture", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString", + "doc": null + }, + { + "name": "Style", + "value_type": { + "kind": "bit_flags", + "value_set": "shadow_type" + }, + "parse_fn": "INI::parseBitString32", + "doc": null + }, + { + "name": "OpacityMin", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityMax", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityThrobTime", + "value_type": { + "kind": "duration" + }, + "parse_fn": "INI::parseDurationUnsignedInt", + "doc": null + }, + { + "name": "Color", + "value_type": { + "kind": "color" + }, + "parse_fn": "INI::parseColorInt", + "doc": null + }, + { + "name": "OnlyVisibleToOwningPlayer", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + } + ], + "sub_blocks": [], + "doc": "RadiusDecalTemplate nested field table." + } + ], "doc": null }, { @@ -29370,8 +35163,17 @@ { "name": "UpgradeOCL", "value_type": { - "kind": "unknown", - "parse_fn": "parseOCLUpgradePair" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "science" + }, + { + "kind": "reference", + "ref_kind": "object_creation_list" + } + ] }, "parse_fn": "parseOCLUpgradePair", "doc": null @@ -29397,7 +35199,8 @@ { "name": "ReferenceObject", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -29432,8 +35235,25 @@ { "name": "FactionOCL", "value_type": { - "kind": "unknown", - "parse_fn": "parseFactionObjectCreationList" + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Faction", + "value_type": { + "kind": "reference", + "ref_kind": "player_template" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] }, "parse_fn": "parseFactionObjectCreationList", "doc": null @@ -29938,8 +35758,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -29971,7 +35799,8 @@ { "name": "PayloadTemplateName", "value_type": { - "kind": "ascii_string_list" + "kind": "reference_list", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiStringVectorAppend", "doc": null @@ -30038,29 +35867,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -30177,8 +35988,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -30186,8 +36005,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -30195,8 +36022,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -30339,8 +36166,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -30348,8 +36183,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -30357,8 +36200,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -30900,22 +36743,6 @@ }, "parse_fn": "INI::parseReal", "doc": null - }, - { - "name": "ExtraHealAmount4Helicopters", - "value_type": { - "kind": "real" - }, - "parse_fn": "INI::parseReal", - "doc": null - }, - { - "name": "TimeForFullHeal", - "value_type": { - "kind": "duration" - }, - "parse_fn": "INI::parseDurationUnsignedInt", - "doc": null } ], "sub_blocks": [], @@ -31011,7 +36838,8 @@ { "name": "OuterNodesLightFlareParticleSystem", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31019,7 +36847,8 @@ { "name": "OuterNodesMediumFlareParticleSystem", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31027,7 +36856,8 @@ { "name": "OuterNodesIntenseFlareParticleSystem", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31043,7 +36873,8 @@ { "name": "ConnectorMediumLaserName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31051,7 +36882,8 @@ { "name": "ConnectorIntenseLaserName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31059,7 +36891,8 @@ { "name": "ConnectorMediumFlare", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31067,7 +36900,8 @@ { "name": "ConnectorIntenseFlare", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31083,7 +36917,8 @@ { "name": "LaserBaseLightFlareParticleSystemName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31091,7 +36926,8 @@ { "name": "LaserBaseMediumFlareParticleSystemName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31099,7 +36935,8 @@ { "name": "LaserBaseIntenseFlareParticleSystemName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31107,7 +36944,8 @@ { "name": "ParticleBeamLaserName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31189,8 +37027,8 @@ { "name": "DamageType", "value_type": { - "kind": "unknown", - "parse_fn": "DamageTypeFlags::parseSingleBitFromINI" + "kind": "enum", + "value_set": "damage_type" }, "parse_fn": "DamageTypeFlags::parseSingleBitFromINI", "doc": null @@ -31215,7 +37053,8 @@ { "name": "PoweringUpSoundLoop", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31223,7 +37062,8 @@ { "name": "UnpackToIdleSoundLoop", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31231,7 +37071,8 @@ { "name": "FiringToPackSoundLoop", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31239,7 +37080,8 @@ { "name": "GroundAnnihilationSoundLoop", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "audio_event" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31247,7 +37089,8 @@ { "name": "DamagePulseRemnantObjectName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -31383,8 +37226,7 @@ { "name": "ForwardFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -31392,8 +37234,7 @@ { "name": "LateralFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -31401,8 +37242,7 @@ { "name": "ZFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -31410,8 +37250,7 @@ { "name": "AerodynamicFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -31451,8 +37290,7 @@ { "name": "MinFallHeightForDamage", "value_type": { - "kind": "unknown", - "parse_fn": "parseHeightToSpeed" + "kind": "real" }, "parse_fn": "parseHeightToSpeed", "doc": null @@ -31966,8 +37804,16 @@ { "name": "QuantityModifier", "value_type": { - "kind": "unknown", - "parse_fn": "parseAppendQuantityModifier" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseAppendQuantityModifier", "doc": null @@ -31975,8 +37821,8 @@ { "name": "DisabledTypesToProcess", "value_type": { - "kind": "unknown", - "parse_fn": "DisabledMaskType::parseFromINI" + "kind": "bit_flags", + "value_set": "disabled_type" }, "parse_fn": "DisabledMaskType::parseFromINI", "doc": null @@ -32256,7 +38102,8 @@ { "name": "UpgradeRequired", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "upgrade" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -32417,25 +38264,7 @@ "interfaces": [ "Update" ], - "fields": [ - { - "name": "DeliveryDecal", - "value_type": { - "kind": "unknown", - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate" - }, - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate", - "doc": null - }, - { - "name": "DeliveryDecalRadius", - "value_type": { - "kind": "real" - }, - "parse_fn": "INI::parseReal", - "doc": null - } - ], + "fields": [], "sub_blocks": [], "doc": null }, @@ -32445,29 +38274,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -32576,8 +38387,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -32585,8 +38404,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -32594,8 +38421,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -32738,8 +38565,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -32747,8 +38582,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -32756,8 +38599,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -33082,8 +38925,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -33223,8 +39074,7 @@ { "name": "ForwardFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -33232,8 +39082,7 @@ { "name": "LateralFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -33241,8 +39090,7 @@ { "name": "ZFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -33250,8 +39098,7 @@ { "name": "AerodynamicFriction", "value_type": { - "kind": "unknown", - "parse_fn": "parseFrictionPerSec" + "kind": "real" }, "parse_fn": "parseFrictionPerSec", "doc": null @@ -33291,8 +39138,7 @@ { "name": "MinFallHeightForDamage", "value_type": { - "kind": "unknown", - "parse_fn": "parseHeightToSpeed" + "kind": "real" }, "parse_fn": "parseHeightToSpeed", "doc": null @@ -33358,7 +39204,8 @@ { "name": "CarriageTemplateName", "value_type": { - "kind": "ascii_string_list" + "kind": "reference_list", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiStringVectorAppend", "doc": null @@ -33486,7 +39333,8 @@ { "name": "WorkerObjectName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -33520,7 +39368,8 @@ { "name": "HoleName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -33624,7 +39473,8 @@ { "name": "ReplaceObject", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -33882,8 +39732,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -33915,8 +39773,33 @@ { "name": "Rider1", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33924,8 +39807,33 @@ { "name": "Rider2", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33933,8 +39841,33 @@ { "name": "Rider3", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33942,8 +39875,33 @@ { "name": "Rider4", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33951,8 +39909,33 @@ { "name": "Rider5", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33960,8 +39943,33 @@ { "name": "Rider6", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33969,8 +39977,33 @@ { "name": "Rider7", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -33978,8 +40011,33 @@ { "name": "Rider8", "value_type": { - "kind": "unknown", - "parse_fn": "parseRiderInfo" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "enum", + "value_set": "model_condition" + }, + { + "kind": "enum", + "value_set": "weapon_set_conditions" + }, + { + "kind": "enum", + "value_set": "object_status" + }, + { + "kind": "reference", + "ref_kind": "command_set" + }, + { + "kind": "enum", + "value_set": "locomotor_set" + } + ] }, "parse_fn": "parseRiderInfo", "doc": null @@ -34126,7 +40184,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -34236,7 +40295,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -34346,7 +40406,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -34464,7 +40525,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -34582,7 +40644,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -34699,118 +40762,120 @@ }, { "name": "ExecuteAnimation", - "value_type": { - "kind": "ascii_string" - }, - "parse_fn": "INI::parseAsciiString", - "doc": null - }, - { - "name": "ExecuteAnimationTime", - "value_type": { - "kind": "real" - }, - "parse_fn": "INI::parseReal", - "doc": null - }, - { - "name": "ExecuteAnimationZRise", - "value_type": { - "kind": "real" - }, - "parse_fn": "INI::parseReal", - "doc": null - }, - { - "name": "ExecuteAnimationFades", - "value_type": { - "kind": "bool" - }, - "parse_fn": "INI::parseBool", - "doc": null - } - ], - "sub_blocks": [], - "doc": null - }, - { - "name": "SabotageSupplyCenterCrateCollide", - "interfaces": [ - "Collide" - ], - "fields": [ - { - "name": "RequiredKindOf", - "value_type": { - "kind": "bit_flags", - "value_set": "kind_of" - }, - "parse_fn": "KindOfMaskType::parseFromINI", - "doc": null - }, - { - "name": "ForbiddenKindOf", - "value_type": { - "kind": "bit_flags", - "value_set": "kind_of" - }, - "parse_fn": "KindOfMaskType::parseFromINI", - "doc": null - }, - { - "name": "ForbidOwnerPlayer", - "value_type": { - "kind": "bool" - }, - "parse_fn": "INI::parseBool", - "doc": null - }, - { - "name": "BuildingPickup", - "value_type": { - "kind": "bool" - }, - "parse_fn": "INI::parseBool", - "doc": null - }, - { - "name": "HumanOnly", - "value_type": { - "kind": "bool" - }, - "parse_fn": "INI::parseBool", - "doc": null - }, - { - "name": "AllowMultiPickup", - "value_type": { - "kind": "bool" - }, - "parse_fn": "INI::parseBool", - "doc": null - }, - { - "name": "PickupScience", - "value_type": { - "kind": "reference", - "ref_kind": "science" - }, - "parse_fn": "INI::parseScience", - "doc": null - }, - { - "name": "ExecuteFX", "value_type": { "kind": "reference", - "ref_kind": "fx_list" - }, - "parse_fn": "INI::parseFXList", - "doc": null - }, - { - "name": "ExecuteAnimation", - "value_type": { - "kind": "ascii_string" + "ref_kind": "anim2_d" + }, + "parse_fn": "INI::parseAsciiString", + "doc": null + }, + { + "name": "ExecuteAnimationTime", + "value_type": { + "kind": "real" + }, + "parse_fn": "INI::parseReal", + "doc": null + }, + { + "name": "ExecuteAnimationZRise", + "value_type": { + "kind": "real" + }, + "parse_fn": "INI::parseReal", + "doc": null + }, + { + "name": "ExecuteAnimationFades", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + } + ], + "sub_blocks": [], + "doc": null + }, + { + "name": "SabotageSupplyCenterCrateCollide", + "interfaces": [ + "Collide" + ], + "fields": [ + { + "name": "RequiredKindOf", + "value_type": { + "kind": "bit_flags", + "value_set": "kind_of" + }, + "parse_fn": "KindOfMaskType::parseFromINI", + "doc": null + }, + { + "name": "ForbiddenKindOf", + "value_type": { + "kind": "bit_flags", + "value_set": "kind_of" + }, + "parse_fn": "KindOfMaskType::parseFromINI", + "doc": null + }, + { + "name": "ForbidOwnerPlayer", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + }, + { + "name": "BuildingPickup", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + }, + { + "name": "HumanOnly", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + }, + { + "name": "AllowMultiPickup", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + }, + { + "name": "PickupScience", + "value_type": { + "kind": "reference", + "ref_kind": "science" + }, + "parse_fn": "INI::parseScience", + "doc": null + }, + { + "name": "ExecuteFX", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + }, + "parse_fn": "INI::parseFXList", + "doc": null + }, + { + "name": "ExecuteAnimation", + "value_type": { + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -34928,7 +40993,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -35046,7 +41112,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -35196,7 +41263,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -35358,7 +41426,8 @@ { "name": "RepairWeldingSys", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -35471,7 +41540,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "fx_list" } ] @@ -35489,7 +41558,7 @@ "value_set": "slow_death_phase" }, { - "kind": "reference", + "kind": "reference_list", "ref_kind": "object_creation_list" } ] @@ -35500,8 +41569,17 @@ { "name": "Weapon", "value_type": { - "kind": "unknown", - "parse_fn": "parseWeapon" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "slow_death_phase" + }, + { + "kind": "reference_list", + "ref_kind": "weapon" + } + ] }, "parse_fn": "parseWeapon", "doc": null @@ -35653,7 +41731,8 @@ { "name": "SpawnTemplateName", "value_type": { - "kind": "ascii_string_list" + "kind": "reference_list", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiStringVectorAppend", "doc": null @@ -35891,7 +41970,8 @@ { "name": "SpecialObject", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -36162,7 +42242,8 @@ { "name": "GunshipTemplateName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -36224,7 +42305,8 @@ { "name": "GattlingTemplateName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -36318,27 +42400,138 @@ }, "parse_fn": "INI::parseParticleSystemTemplate", "doc": null - }, + } + ], + "sub_blocks": [ { - "name": "AttackAreaDecal", - "value_type": { - "kind": "unknown", - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate" - }, - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate", - "doc": null + "keyword": "AttackAreaDecal", + "fields": [ + { + "name": "Texture", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString", + "doc": null + }, + { + "name": "Style", + "value_type": { + "kind": "bit_flags", + "value_set": "shadow_type" + }, + "parse_fn": "INI::parseBitString32", + "doc": null + }, + { + "name": "OpacityMin", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityMax", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityThrobTime", + "value_type": { + "kind": "duration" + }, + "parse_fn": "INI::parseDurationUnsignedInt", + "doc": null + }, + { + "name": "Color", + "value_type": { + "kind": "color" + }, + "parse_fn": "INI::parseColorInt", + "doc": null + }, + { + "name": "OnlyVisibleToOwningPlayer", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + } + ], + "sub_blocks": [], + "doc": "RadiusDecalTemplate nested field table." }, { - "name": "TargetingReticleDecal", - "value_type": { - "kind": "unknown", - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate" - }, - "parse_fn": "RadiusDecalTemplate::parseRadiusDecalTemplate", - "doc": null + "keyword": "TargetingReticleDecal", + "fields": [ + { + "name": "Texture", + "value_type": { + "kind": "ascii_string" + }, + "parse_fn": "INI::parseAsciiString", + "doc": null + }, + { + "name": "Style", + "value_type": { + "kind": "bit_flags", + "value_set": "shadow_type" + }, + "parse_fn": "INI::parseBitString32", + "doc": null + }, + { + "name": "OpacityMin", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityMax", + "value_type": { + "kind": "percent" + }, + "parse_fn": "INI::parsePercentToReal", + "doc": null + }, + { + "name": "OpacityThrobTime", + "value_type": { + "kind": "duration" + }, + "parse_fn": "INI::parseDurationUnsignedInt", + "doc": null + }, + { + "name": "Color", + "value_type": { + "kind": "color" + }, + "parse_fn": "INI::parseColorInt", + "doc": null + }, + { + "name": "OnlyVisibleToOwningPlayer", + "value_type": { + "kind": "bool" + }, + "parse_fn": "INI::parseBool", + "doc": null + } + ], + "sub_blocks": [], + "doc": "RadiusDecalTemplate nested field table." } ], - "sub_blocks": [], "doc": null }, { @@ -36748,7 +42941,8 @@ { "name": "StealthForbiddenConditions", "value_type": { - "kind": "unknown", + "kind": "enum", + "value_set": "stealth_level", "parse_fn": "INI::parseBitString32" }, "parse_fn": "INI::parseBitString32", @@ -36882,8 +43076,8 @@ { "name": "EnemyDetectionEvaEvent", "value_type": { - "kind": "unknown", - "parse_fn": "Eva::parseEvaMessageFromIni" + "kind": "reference", + "ref_kind": "eva_event" }, "parse_fn": "Eva::parseEvaMessageFromIni", "doc": null @@ -36891,8 +43085,8 @@ { "name": "OwnDetectionEvaEvent", "value_type": { - "kind": "unknown", - "parse_fn": "Eva::parseEvaMessageFromIni" + "kind": "reference", + "ref_kind": "eva_event" }, "parse_fn": "Eva::parseEvaMessageFromIni", "doc": null @@ -37314,7 +43508,8 @@ { "name": "CrushingWeaponName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "weapon" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -37340,8 +43535,16 @@ { "name": "AngleFX", "value_type": { - "kind": "unknown", - "parse_fn": "parseAngleFX" + "kind": "token_list", + "tokens": [ + { + "kind": "angle_real" + }, + { + "kind": "reference", + "ref_kind": "fx_list" + } + ] }, "parse_fn": "parseAngleFX", "doc": null @@ -37539,29 +43742,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -37703,8 +43888,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -37712,8 +43905,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -37721,8 +43922,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -37865,8 +44066,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -37874,8 +44083,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -37883,8 +44100,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -38143,7 +44360,8 @@ { "name": "StumpName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -38222,15 +44440,6 @@ "Damage" ], "fields": [ - { - "name": "DamageTypes", - "value_type": { - "kind": "bit_flags", - "value_set": "damage_type" - }, - "parse_fn": "INI::parseDamageTypeFlags", - "doc": null - }, { "name": "DamageFXTypes", "value_type": { @@ -38261,8 +44470,70 @@ { "name": "DamagedFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38270,8 +44541,70 @@ { "name": "DamagedFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38279,8 +44612,70 @@ { "name": "DamagedFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38288,8 +44683,70 @@ { "name": "DamagedFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38297,8 +44754,70 @@ { "name": "DamagedFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38306,8 +44825,70 @@ { "name": "DamagedFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38315,8 +44896,70 @@ { "name": "DamagedFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38324,8 +44967,70 @@ { "name": "DamagedFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38333,8 +45038,70 @@ { "name": "DamagedFXList9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38342,8 +45109,70 @@ { "name": "DamagedFXList10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38351,8 +45180,70 @@ { "name": "DamagedFXList11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38360,8 +45251,70 @@ { "name": "DamagedFXList12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38369,8 +45322,70 @@ { "name": "ReallyDamagedFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38378,8 +45393,70 @@ { "name": "ReallyDamagedFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38387,8 +45464,70 @@ { "name": "ReallyDamagedFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38396,8 +45535,70 @@ { "name": "ReallyDamagedFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38405,8 +45606,70 @@ { "name": "ReallyDamagedFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38414,8 +45677,70 @@ { "name": "ReallyDamagedFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38423,8 +45748,70 @@ { "name": "ReallyDamagedFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38432,8 +45819,70 @@ { "name": "ReallyDamagedFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38441,8 +45890,70 @@ { "name": "ReallyDamagedFXList9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38450,8 +45961,70 @@ { "name": "ReallyDamagedFXList10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38459,8 +46032,70 @@ { "name": "ReallyDamagedFXList11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38468,8 +46103,70 @@ { "name": "ReallyDamagedFXList12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38477,8 +46174,70 @@ { "name": "RubbleFXList1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38486,8 +46245,70 @@ { "name": "RubbleFXList2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38495,8 +46316,70 @@ { "name": "RubbleFXList3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38504,8 +46387,70 @@ { "name": "RubbleFXList4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38513,8 +46458,70 @@ { "name": "RubbleFXList5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38522,8 +46529,70 @@ { "name": "RubbleFXList6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38531,8 +46600,70 @@ { "name": "RubbleFXList7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38540,8 +46671,70 @@ { "name": "RubbleFXList8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38549,8 +46742,70 @@ { "name": "RubbleFXList9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38558,8 +46813,70 @@ { "name": "RubbleFXList10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38567,8 +46884,70 @@ { "name": "RubbleFXList11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38576,8 +46955,70 @@ { "name": "RubbleFXList12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseFXList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "FXList", + "value_type": { + "kind": "reference", + "ref_kind": "fx_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseFXList", "doc": null @@ -38585,8 +47026,70 @@ { "name": "DamagedOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38594,8 +47097,70 @@ { "name": "DamagedOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38603,8 +47168,70 @@ { "name": "DamagedOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38612,8 +47239,70 @@ { "name": "DamagedOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38621,8 +47310,70 @@ { "name": "DamagedOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38630,8 +47381,70 @@ { "name": "DamagedOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38639,8 +47452,70 @@ { "name": "DamagedOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38648,8 +47523,70 @@ { "name": "DamagedOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38657,8 +47594,70 @@ { "name": "DamagedOCL9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38666,8 +47665,70 @@ { "name": "DamagedOCL10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38675,8 +47736,70 @@ { "name": "DamagedOCL11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38684,8 +47807,70 @@ { "name": "DamagedOCL12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38693,8 +47878,70 @@ { "name": "ReallyDamagedOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38702,8 +47949,70 @@ { "name": "ReallyDamagedOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38711,8 +48020,70 @@ { "name": "ReallyDamagedOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38720,8 +48091,70 @@ { "name": "ReallyDamagedOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38729,8 +48162,70 @@ { "name": "ReallyDamagedOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38738,8 +48233,70 @@ { "name": "ReallyDamagedOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38747,8 +48304,70 @@ { "name": "ReallyDamagedOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38756,8 +48375,70 @@ { "name": "ReallyDamagedOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38765,8 +48446,70 @@ { "name": "ReallyDamagedOCL9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38774,8 +48517,70 @@ { "name": "ReallyDamagedOCL10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38783,8 +48588,70 @@ { "name": "ReallyDamagedOCL11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38792,8 +48659,70 @@ { "name": "ReallyDamagedOCL12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38801,8 +48730,70 @@ { "name": "RubbleOCL1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38810,8 +48801,70 @@ { "name": "RubbleOCL2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38819,8 +48872,70 @@ { "name": "RubbleOCL3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38828,8 +48943,70 @@ { "name": "RubbleOCL4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38837,8 +49014,70 @@ { "name": "RubbleOCL5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38846,8 +49085,70 @@ { "name": "RubbleOCL6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38855,8 +49156,70 @@ { "name": "RubbleOCL7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38864,8 +49227,70 @@ { "name": "RubbleOCL8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38873,8 +49298,70 @@ { "name": "RubbleOCL9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38882,8 +49369,70 @@ { "name": "RubbleOCL10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38891,8 +49440,70 @@ { "name": "RubbleOCL11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38900,8 +49511,70 @@ { "name": "RubbleOCL12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "OCL", + "value_type": { + "kind": "reference", + "ref_kind": "object_creation_list" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseObjectCreationList", "doc": null @@ -38909,8 +49582,70 @@ { "name": "DamagedParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38918,8 +49653,70 @@ { "name": "DamagedParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38927,8 +49724,70 @@ { "name": "DamagedParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38936,8 +49795,70 @@ { "name": "DamagedParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38945,8 +49866,70 @@ { "name": "DamagedParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38954,8 +49937,70 @@ { "name": "DamagedParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38963,8 +50008,70 @@ { "name": "DamagedParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38972,8 +50079,70 @@ { "name": "DamagedParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38981,8 +50150,70 @@ { "name": "DamagedParticleSystem9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38990,8 +50221,70 @@ { "name": "DamagedParticleSystem10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -38999,8 +50292,70 @@ { "name": "DamagedParticleSystem11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39008,8 +50363,70 @@ { "name": "DamagedParticleSystem12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39017,8 +50434,70 @@ { "name": "ReallyDamagedParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39026,8 +50505,70 @@ { "name": "ReallyDamagedParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39035,8 +50576,70 @@ { "name": "ReallyDamagedParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39044,8 +50647,70 @@ { "name": "ReallyDamagedParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39053,8 +50718,70 @@ { "name": "ReallyDamagedParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39062,8 +50789,70 @@ { "name": "ReallyDamagedParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39071,8 +50860,70 @@ { "name": "ReallyDamagedParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39080,8 +50931,70 @@ { "name": "ReallyDamagedParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39089,8 +51002,70 @@ { "name": "ReallyDamagedParticleSystem9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39098,8 +51073,70 @@ { "name": "ReallyDamagedParticleSystem10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39107,8 +51144,70 @@ { "name": "ReallyDamagedParticleSystem11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39116,8 +51215,70 @@ { "name": "ReallyDamagedParticleSystem12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39125,8 +51286,70 @@ { "name": "RubbleParticleSystem1", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39134,8 +51357,70 @@ { "name": "RubbleParticleSystem2", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39143,8 +51428,70 @@ { "name": "RubbleParticleSystem3", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39152,8 +51499,70 @@ { "name": "RubbleParticleSystem4", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39161,8 +51570,70 @@ { "name": "RubbleParticleSystem5", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39170,8 +51641,70 @@ { "name": "RubbleParticleSystem6", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39179,8 +51712,70 @@ { "name": "RubbleParticleSystem7", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39188,8 +51783,70 @@ { "name": "RubbleParticleSystem8", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39197,8 +51854,70 @@ { "name": "RubbleParticleSystem9", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39206,8 +51925,70 @@ { "name": "RubbleParticleSystem10", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39215,8 +51996,70 @@ { "name": "RubbleParticleSystem11", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39224,8 +52067,70 @@ { "name": "RubbleParticleSystem12", "value_type": { - "kind": "unknown", - "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem" + "kind": "one_of", + "variants": [ + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Bone", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "RandomBone", + "value_type": { + "kind": "bool" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + }, + { + "kind": "token_list", + "tokens": [ + { + "kind": "prefixed", + "prefix": "Loc", + "value_type": { + "kind": "ascii_string" + } + }, + { + "kind": "prefixed", + "prefix": "Y", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "Z", + "value_type": { + "kind": "real" + } + }, + { + "kind": "prefixed", + "prefix": "PSys", + "value_type": { + "kind": "reference", + "ref_kind": "particle_system" + } + } + ] + } + ] }, "parse_fn": "TransitionDamageFXModuleData::parseParticleSystem", "doc": null @@ -39240,29 +52145,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -39363,8 +52250,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -39372,8 +52267,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -39381,8 +52284,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -39525,8 +52428,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -39534,8 +52445,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -39543,8 +52462,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -39833,8 +52752,16 @@ { "name": "InitialPayload", "value_type": { - "kind": "unknown", - "parse_fn": "parseInitialPayload" + "kind": "token_list", + "tokens": [ + { + "kind": "reference", + "ref_kind": "object" + }, + { + "kind": "int" + } + ] }, "parse_fn": "parseInitialPayload", "doc": null @@ -40224,7 +53151,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -40264,7 +53192,8 @@ { "name": "UnitName", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "object" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -40345,7 +53274,8 @@ { "name": "UpgradeToRemove", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "upgrade" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -40467,7 +53397,8 @@ { "name": "ExecuteAnimation", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "anim2_d" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -40644,8 +53575,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -40716,7 +53647,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -40724,7 +53655,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40740,7 +53671,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40756,7 +53687,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40772,7 +53703,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40788,7 +53719,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -40796,7 +53727,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -40804,7 +53735,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -40812,7 +53752,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -40820,7 +53769,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -40828,7 +53786,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -40836,7 +53803,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -40894,8 +53870,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -40903,8 +53887,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -40921,7 +53912,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -40929,7 +53920,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40945,7 +53936,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40961,7 +53952,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40977,7 +53968,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -40993,7 +53984,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41001,7 +53992,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41009,7 +54000,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41017,7 +54017,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41025,7 +54034,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41033,7 +54051,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41041,7 +54068,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41099,8 +54135,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -41108,8 +54152,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -41129,7 +54180,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -41137,7 +54188,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41153,7 +54204,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41169,7 +54220,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41185,7 +54236,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41201,7 +54252,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41209,7 +54260,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41217,7 +54268,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41225,7 +54285,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41233,7 +54302,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41241,7 +54319,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41249,7 +54336,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41307,8 +54403,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -41316,8 +54420,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -41527,8 +54638,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -41591,7 +54702,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -41599,7 +54710,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41615,7 +54726,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41631,7 +54742,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41647,7 +54758,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41663,7 +54774,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41671,7 +54782,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41679,7 +54790,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41687,7 +54807,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41695,7 +54824,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41703,7 +54841,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41711,7 +54858,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41769,8 +54925,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -41778,8 +54942,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -41796,7 +54967,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -41804,7 +54975,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41820,7 +54991,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41836,7 +55007,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41852,7 +55023,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -41868,7 +55039,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41876,7 +55047,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -41884,7 +55055,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41892,7 +55072,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41900,7 +55089,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41908,7 +55106,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41916,7 +55123,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -41974,8 +55190,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -41983,8 +55207,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -42004,7 +55235,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -42012,7 +55243,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42028,7 +55259,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42044,7 +55275,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42060,7 +55291,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42076,7 +55307,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42084,7 +55315,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42092,7 +55323,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42100,7 +55340,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42108,7 +55357,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42116,7 +55374,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42124,7 +55391,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42182,8 +55458,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -42191,8 +55475,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -42280,8 +55571,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -42330,7 +55621,8 @@ { "name": "TreadDebrisLeft", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -42338,7 +55630,8 @@ { "name": "TreadDebrisRight", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -42384,7 +55677,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -42392,7 +55685,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42408,7 +55701,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42424,7 +55717,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42440,7 +55733,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42456,7 +55749,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42464,7 +55757,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42472,7 +55765,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42480,7 +55782,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42488,7 +55799,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42496,7 +55816,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42504,7 +55833,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42562,8 +55900,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -42571,8 +55917,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -42589,7 +55942,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -42597,7 +55950,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42613,7 +55966,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42629,7 +55982,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42645,7 +55998,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42661,7 +56014,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42669,7 +56022,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42677,7 +56030,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42685,7 +56047,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42693,7 +56064,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42701,7 +56081,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42709,7 +56098,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42767,8 +56165,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -42776,8 +56182,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -42797,7 +56210,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -42805,7 +56218,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42821,7 +56234,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42837,7 +56250,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42853,7 +56266,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -42869,7 +56282,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42877,7 +56290,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -42885,7 +56298,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42893,7 +56315,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42901,7 +56332,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42909,7 +56349,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42917,7 +56366,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -42975,8 +56433,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -42984,8 +56450,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -43073,8 +56546,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -43123,7 +56596,8 @@ { "name": "Dust", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -43131,7 +56605,8 @@ { "name": "DirtSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -43139,7 +56614,8 @@ { "name": "PowerslideSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -43297,7 +56773,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -43305,7 +56781,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43321,7 +56797,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43337,7 +56813,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43353,7 +56829,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43369,7 +56845,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -43377,7 +56853,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -43385,7 +56861,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43393,7 +56878,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43401,7 +56895,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43409,7 +56912,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43417,7 +56929,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43475,8 +56996,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -43484,8 +57013,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -43502,7 +57038,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -43510,7 +57046,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43526,7 +57062,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43542,7 +57078,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43558,7 +57094,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43574,7 +57110,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -43582,7 +57118,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -43590,7 +57126,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43598,7 +57143,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43606,7 +57160,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43614,7 +57177,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43622,7 +57194,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43680,8 +57261,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -43689,8 +57278,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -43710,7 +57306,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -43718,7 +57314,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43734,7 +57330,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43750,7 +57346,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43766,7 +57362,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -43782,7 +57378,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -43790,7 +57386,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -43798,7 +57394,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43806,7 +57411,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43814,7 +57428,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43822,7 +57445,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43830,7 +57462,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -43888,8 +57529,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -43897,8 +57546,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -43986,8 +57642,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -44036,7 +57692,8 @@ { "name": "Dust", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -44044,7 +57701,8 @@ { "name": "DirtSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -44052,7 +57710,8 @@ { "name": "PowerslideSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -44210,7 +57869,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -44218,7 +57877,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44234,7 +57893,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44250,7 +57909,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44266,7 +57925,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44282,7 +57941,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -44290,7 +57949,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -44298,7 +57957,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44306,7 +57974,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44314,7 +57991,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44322,7 +58008,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44330,7 +58025,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44388,8 +58092,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -44397,8 +58109,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -44415,7 +58134,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -44423,7 +58142,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44439,7 +58158,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44455,7 +58174,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44471,7 +58190,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44487,7 +58206,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -44495,7 +58214,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -44503,7 +58222,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44511,7 +58239,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44519,7 +58256,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44527,7 +58273,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44535,7 +58290,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44593,8 +58357,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -44602,8 +58374,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -44623,7 +58402,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -44631,7 +58410,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44647,7 +58426,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44663,7 +58442,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44679,7 +58458,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -44695,7 +58474,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -44703,7 +58482,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -44711,7 +58490,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44719,7 +58507,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44727,7 +58524,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44735,7 +58541,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44743,7 +58558,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -44801,8 +58625,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -44810,8 +58642,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -44884,7 +58723,7 @@ { "name": "ModelName", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -44976,8 +58815,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -45049,7 +58888,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -45057,7 +58896,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45073,7 +58912,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45089,7 +58928,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45105,7 +58944,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45121,7 +58960,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45129,7 +58968,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45137,7 +58976,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45145,7 +58993,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45153,7 +59010,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45161,7 +59027,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45169,7 +59044,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45227,8 +59111,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -45236,8 +59128,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -45254,7 +59153,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -45262,7 +59161,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45278,7 +59177,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45294,7 +59193,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45310,7 +59209,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45326,7 +59225,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45334,7 +59233,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45342,7 +59241,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45350,7 +59258,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45358,7 +59275,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45366,7 +59292,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45374,7 +59309,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45432,8 +59376,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -45441,8 +59393,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -45462,7 +59421,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -45470,7 +59429,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45486,7 +59445,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45502,7 +59461,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45518,7 +59477,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45534,7 +59493,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45542,7 +59501,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45550,7 +59509,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45558,7 +59526,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45566,7 +59543,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45574,7 +59560,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45582,7 +59577,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45640,8 +59644,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -45649,8 +59661,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -45738,8 +59757,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -45810,7 +59829,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -45818,7 +59837,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45834,7 +59853,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45850,7 +59869,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45866,7 +59885,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -45882,7 +59901,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45890,7 +59909,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -45898,7 +59917,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45906,7 +59934,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45914,7 +59951,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45922,7 +59968,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45930,7 +59985,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -45988,8 +60052,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -45997,8 +60069,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -46015,7 +60094,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -46023,7 +60102,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46039,7 +60118,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46055,7 +60134,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46071,7 +60150,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46087,7 +60166,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46095,7 +60174,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46103,7 +60182,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46111,7 +60199,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46119,7 +60216,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46127,7 +60233,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46135,7 +60250,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46193,8 +60317,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -46202,8 +60334,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -46223,7 +60362,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -46231,7 +60370,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46247,7 +60386,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46263,7 +60402,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46279,7 +60418,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46295,7 +60434,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46303,7 +60442,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46311,7 +60450,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46319,7 +60467,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46327,7 +60484,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46335,7 +60501,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46343,7 +60518,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46401,8 +60585,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -46410,8 +60602,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -46499,8 +60698,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -46549,7 +60748,8 @@ { "name": "TreadDebrisLeft", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -46557,7 +60757,8 @@ { "name": "TreadDebrisRight", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -46603,7 +60804,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -46611,7 +60812,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46627,7 +60828,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46643,7 +60844,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46659,7 +60860,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46675,7 +60876,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46683,7 +60884,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46691,7 +60892,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46699,7 +60909,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46707,7 +60926,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46715,7 +60943,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46723,7 +60960,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46781,8 +61027,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -46790,8 +61044,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -46808,7 +61069,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -46816,7 +61077,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46832,7 +61093,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46848,7 +61109,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46864,7 +61125,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -46880,7 +61141,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46888,7 +61149,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -46896,7 +61157,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46904,7 +61174,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46912,7 +61191,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46920,7 +61208,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46928,7 +61225,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -46986,8 +61292,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -46995,8 +61309,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -47016,7 +61337,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -47024,7 +61345,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47040,7 +61361,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47056,7 +61377,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47072,7 +61393,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47088,7 +61409,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47096,7 +61417,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47104,7 +61425,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47112,7 +61442,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47120,7 +61459,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47128,7 +61476,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47136,7 +61493,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47194,8 +61560,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -47203,8 +61577,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -47292,8 +61673,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -47342,7 +61723,8 @@ { "name": "Dust", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -47350,7 +61732,8 @@ { "name": "DirtSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -47358,7 +61741,8 @@ { "name": "PowerslideSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -47446,7 +61830,8 @@ { "name": "TreadDebrisLeft", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -47454,7 +61839,8 @@ { "name": "TreadDebrisRight", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -47500,7 +61886,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -47508,7 +61894,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47524,7 +61910,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47540,7 +61926,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47556,7 +61942,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47572,7 +61958,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47580,7 +61966,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47588,7 +61974,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47596,7 +61991,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47604,7 +62008,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47612,7 +62025,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47620,7 +62042,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47678,8 +62109,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -47687,8 +62126,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -47705,7 +62151,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -47713,7 +62159,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47729,7 +62175,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47745,7 +62191,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47761,7 +62207,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47777,7 +62223,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47785,7 +62231,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47793,7 +62239,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47801,7 +62256,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47809,7 +62273,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47817,7 +62290,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47825,7 +62307,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -47883,8 +62374,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -47892,8 +62391,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -47913,7 +62419,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -47921,7 +62427,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47937,7 +62443,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47953,7 +62459,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47969,7 +62475,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -47985,7 +62491,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -47993,7 +62499,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -48001,7 +62507,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48009,7 +62524,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48017,7 +62541,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48025,7 +62558,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48033,7 +62575,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48091,8 +62642,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -48100,8 +62659,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -48133,7 +62699,7 @@ { "name": "ModelName", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -48199,7 +62765,7 @@ { "name": "StumpName", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -48354,8 +62920,8 @@ { "name": "ProjectileBoneFeedbackEnabledSlots", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -48404,7 +62970,8 @@ { "name": "Dust", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -48412,7 +62979,8 @@ { "name": "DirtSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -48420,7 +62988,8 @@ { "name": "PowerslideSpray", "value_type": { - "kind": "ascii_string" + "kind": "reference", + "ref_kind": "particle_system" }, "parse_fn": "INI::parseAsciiString", "doc": null @@ -48578,7 +63147,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -48586,7 +63155,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48602,7 +63171,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48618,7 +63187,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48634,7 +63203,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48650,7 +63219,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -48658,7 +63227,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -48666,7 +63235,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48674,7 +63252,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48682,7 +63269,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48690,7 +63286,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48698,7 +63303,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48756,8 +63370,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -48765,8 +63387,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -48783,7 +63412,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -48791,7 +63420,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48807,7 +63436,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48823,7 +63452,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48839,7 +63468,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -48855,7 +63484,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -48863,7 +63492,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -48871,7 +63500,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48879,7 +63517,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48887,7 +63534,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48895,7 +63551,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48903,7 +63568,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -48961,8 +63635,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -48970,8 +63652,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -48991,7 +63680,7 @@ { "name": "Model", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model" }, "parse_fn": "parseAsciiStringLC", "doc": null @@ -48999,7 +63688,7 @@ { "name": "Turret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -49015,7 +63704,7 @@ { "name": "TurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -49031,7 +63720,7 @@ { "name": "AltTurret", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -49047,7 +63736,7 @@ { "name": "AltTurretPitch", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseBoneNameKey", "doc": null @@ -49063,7 +63752,7 @@ { "name": "ShowSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -49071,7 +63760,7 @@ { "name": "HideSubObject", "value_type": { - "kind": "ascii_string" + "kind": "w3d_model_member" }, "parse_fn": "parseShowHideSubObject", "doc": null @@ -49079,7 +63768,16 @@ { "name": "WeaponFireFXBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -49087,7 +63785,16 @@ { "name": "WeaponRecoilBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -49095,7 +63802,16 @@ { "name": "WeaponMuzzleFlash", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -49103,7 +63819,16 @@ { "name": "WeaponLaunchBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -49111,7 +63836,16 @@ { "name": "WeaponHideShowBone", "value_type": { - "kind": "ascii_string" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "w3d_model_member" + } + ] }, "parse_fn": "parseWeaponBoneName", "doc": null @@ -49169,8 +63903,16 @@ { "name": "ParticleSysBone", "value_type": { - "kind": "unknown", - "parse_fn": "parseParticleSysBone" + "kind": "token_list", + "tokens": [ + { + "kind": "w3d_model_member" + }, + { + "kind": "reference", + "ref_kind": "particle_system" + } + ] }, "parse_fn": "parseParticleSysBone", "doc": null @@ -49178,8 +63920,15 @@ { "name": "AnimationSpeedFactorRange", "value_type": { - "kind": "unknown", - "parse_fn": "parseRealRange" + "kind": "token_list", + "tokens": [ + { + "kind": "real" + }, + { + "kind": "real" + } + ] }, "parse_fn": "parseRealRange", "doc": null @@ -49199,29 +63948,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -49322,8 +64053,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -49331,8 +64070,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -49340,8 +64087,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -49484,8 +64231,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -49493,8 +64248,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -49502,8 +64265,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -49895,29 +64658,11 @@ "Update" ], "fields": [ - { - "name": "Turret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, - { - "name": "AltTurret", - "value_type": { - "kind": "unknown", - "parse_fn": "AIUpdateModuleData::parseTurret" - }, - "parse_fn": "AIUpdateModuleData::parseTurret", - "doc": null - }, { "name": "AutoAcquireEnemiesWhenIdle", "value_type": { - "kind": "unknown", - "parse_fn": "INI::parseBitString32" + "kind": "bit_flags", + "value_set": "auto_acquire_enemies" }, "parse_fn": "INI::parseBitString32", "doc": null @@ -50091,8 +64836,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -50100,8 +64853,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -50109,8 +64870,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -50253,8 +65014,16 @@ { "name": "TurretFireAngleSweep", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweep" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "angle_real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweep", "doc": null @@ -50262,8 +65031,16 @@ { "name": "TurretSweepSpeedModifier", "value_type": { - "kind": "unknown", - "parse_fn": "TurretAIData::parseTurretSweepSpeed" + "kind": "token_list", + "tokens": [ + { + "kind": "enum", + "value_set": "weapon_slot" + }, + { + "kind": "real" + } + ] }, "parse_fn": "TurretAIData::parseTurretSweepSpeed", "doc": null @@ -50271,8 +65048,8 @@ { "name": "ControlledWeaponSlots", "value_type": { - "kind": "unknown", - "parse_fn": "parseTWS" + "kind": "bit_flags", + "value_set": "weapon_slot" }, "parse_fn": "parseTWS", "doc": null @@ -50358,6 +65135,321 @@ } ], "value_sets": [ + { + "id": "stealth_level", + "members": [ + { + "name": "ATTACKING", + "value": 1 + }, + { + "name": "MOVING", + "value": 2 + }, + { + "name": "USING_ABILITY", + "value": 3 + }, + { + "name": "FIRING_PRIMARY", + "value": 4 + }, + { + "name": "FIRING_SECONDARY", + "value": 5 + }, + { + "name": "FIRING_TERTIARY", + "value": 7 + }, + { + "name": "NO_BLACK_MARKET", + "value": 8 + }, + { + "name": "TAKING_DAMAGE", + "value": 9 + }, + { + "name": "RIDERS_ATTACKING", + "value": 10 + } + ] + }, + { + "id": "command_button_command", + "members": [ + { + "name": "NONE", + "value": 0 + }, + { + "name": "DOZER_CONSTRUCT", + "value": 1 + }, + { + "name": "DOZER_CONSTRUCT_CANCEL", + "value": 2 + }, + { + "name": "UNIT_BUILD", + "value": 3 + }, + { + "name": "CANCEL_UNIT_BUILD", + "value": 4 + }, + { + "name": "PLAYER_UPGRADE", + "value": 5 + }, + { + "name": "OBJECT_UPGRADE", + "value": 6 + }, + { + "name": "CANCEL_UPGRADE", + "value": 7 + }, + { + "name": "ATTACK_MOVE", + "value": 8 + }, + { + "name": "GUARD", + "value": 9 + }, + { + "name": "GUARD_WITHOUT_PURSUIT", + "value": 10 + }, + { + "name": "GUARD_FLYING_UNITS_ONLY", + "value": 11 + }, + { + "name": "STOP", + "value": 12 + }, + { + "name": "WAYPOINTS", + "value": 13 + }, + { + "name": "EXIT_CONTAINER", + "value": 14 + }, + { + "name": "EVACUATE", + "value": 15 + }, + { + "name": "EXECUTE_RAILED_TRANSPORT", + "value": 16 + }, + { + "name": "BEACON_DELETE", + "value": 17 + }, + { + "name": "SET_RALLY_POINT", + "value": 18 + }, + { + "name": "SELL", + "value": 19 + }, + { + "name": "FIRE_WEAPON", + "value": 20 + }, + { + "name": "SPECIAL_POWER", + "value": 21 + }, + { + "name": "PURCHASE_SCIENCE", + "value": 22 + }, + { + "name": "HACK_INTERNET", + "value": 23 + }, + { + "name": "TOGGLE_OVERCHARGE", + "value": 24 + }, + { + "name": "COMBATDROP", + "value": 25 + }, + { + "name": "SWITCH_WEAPON", + "value": 26 + }, + { + "name": "HIJACK_VEHICLE", + "value": 27 + }, + { + "name": "CONVERT_TO_CARBOMB", + "value": 28 + }, + { + "name": "SABOTAGE_BUILDING", + "value": 29 + }, + { + "name": "PLACE_BEACON", + "value": 30 + }, + { + "name": "SPECIAL_POWER_FROM_SHORTCUT", + "value": 31 + }, + { + "name": "SPECIAL_POWER_CONSTRUCT", + "value": 32 + }, + { + "name": "SPECIAL_POWER_CONSTRUCT_FROM_SHORTCUT", + "value": 33 + }, + { + "name": "SELECT_ALL_UNITS_OF_TYPE", + "value": 34 + } + ], + "doc": "TheGuiCommandNames (ControlBar.h)" + }, + { + "id": "command_button_options", + "members": [ + { + "name": "NEED_TARGET_ENEMY_OBJECT", + "value": 0 + }, + { + "name": "NEED_TARGET_NEUTRAL_OBJECT", + "value": 1 + }, + { + "name": "NEED_TARGET_ALLY_OBJECT", + "value": 2 + }, + { + "name": "unused-reserved", + "value": 3 + }, + { + "name": "ALLOW_SHRUBBERY_TARGET", + "value": 4 + }, + { + "name": "NEED_TARGET_POS", + "value": 5 + }, + { + "name": "NEED_UPGRADE", + "value": 6 + }, + { + "name": "NEED_SPECIAL_POWER_SCIENCE", + "value": 7 + }, + { + "name": "OK_FOR_MULTI_SELECT", + "value": 8 + }, + { + "name": "CONTEXTMODE_COMMAND", + "value": 9 + }, + { + "name": "CHECK_LIKE", + "value": 10 + }, + { + "name": "ALLOW_MINE_TARGET", + "value": 11 + }, + { + "name": "ATTACK_OBJECTS_POSITION", + "value": 12 + }, + { + "name": "OPTION_ONE", + "value": 13 + }, + { + "name": "OPTION_TWO", + "value": 14 + }, + { + "name": "OPTION_THREE", + "value": 15 + }, + { + "name": "NOT_QUEUEABLE", + "value": 16 + }, + { + "name": "SINGLE_USE_COMMAND", + "value": 17 + }, + { + "name": "---DO-NOT-USE---", + "value": 18 + }, + { + "name": "SCRIPT_ONLY", + "value": 19 + }, + { + "name": "IGNORES_UNDERPOWERED", + "value": 20 + }, + { + "name": "USES_MINE_CLEARING_WEAPONSET", + "value": 21 + }, + { + "name": "CAN_USE_WAYPOINTS", + "value": 22 + }, + { + "name": "MUST_BE_STOPPED", + "value": 23 + } + ], + "doc": "TheCommandOptionNames (ControlBar.h)" + }, + { + "id": "command_button_border_type", + "members": [ + { + "name": "NONE", + "value": 0 + }, + { + "name": "BUILD", + "value": 1 + }, + { + "name": "UPGRADE", + "value": 2 + }, + { + "name": "ACTION", + "value": 3 + }, + { + "name": "SYSTEM", + "value": 4 + } + ], + "doc": "CommandButtonMappedBorderTypeNames (ControlBar.h)" + }, { "id": "ai_side", "members": [ @@ -50967,6 +66059,56 @@ } ] }, + { + "id": "command_source", + "members": [ + { + "name": "FROM_PLAYER", + "value": 0 + }, + { + "name": "FROM_SCRIPT", + "value": 1 + }, + { + "name": "FROM_AI", + "value": 2 + }, + { + "name": "FROM_DOZER", + "value": 3 + }, + { + "name": "DEFAULT_SWITCH_WEAPON", + "value": 4 + } + ] + }, + { + "id": "auto_acquire_enemies", + "members": [ + { + "name": "YES", + "value": 0 + }, + { + "name": "STEALTHED", + "value": 1 + }, + { + "name": "NO", + "value": 2 + }, + { + "name": "NOTWHILEATTACKING", + "value": 3 + }, + { + "name": "ATTACK_BUILDINGS", + "value": 4 + } + ] + }, { "id": "shadow_type", "members": [ @@ -52518,6 +67660,32 @@ ], "doc": "TheRadiusCursorNames (InGameUI.h)" }, + { + "id": "locomotor_surface", + "members": [ + { + "name": "GROUND", + "value": 0 + }, + { + "name": "WATER", + "value": 1 + }, + { + "name": "CLIFF", + "value": 2 + }, + { + "name": "AIR", + "value": 3 + }, + { + "name": "RUBBLE", + "value": 4 + } + ], + "doc": "TheLocomotorSurfaceTypeNames (LocomotorSet.h)" + }, { "id": "locomotor_appearance", "members": [ @@ -54160,6 +69328,113 @@ } ] }, + { + "id": "disabled_type", + "members": [ + { + "name": "DEFAULT", + "value": 0 + }, + { + "name": "DISABLED_HACKED", + "value": 1 + }, + { + "name": "DISABLED_EMP", + "value": 2 + }, + { + "name": "DISABLED_HELD", + "value": 3 + }, + { + "name": "DISABLED_PARALYZED", + "value": 4 + }, + { + "name": "DISABLED_UNMANNED", + "value": 5 + }, + { + "name": "DISABLED_UNDERPOWERED", + "value": 6 + }, + { + "name": "DISABLED_FREEFALL", + "value": 7 + }, + { + "name": "DISABLED_AWESTRUCK", + "value": 8 + }, + { + "name": "DISABLED_BRAINWASHED", + "value": 9 + }, + { + "name": "DISABLED_SUBDUED", + "value": 10 + }, + { + "name": "DISABLED_SCRIPT_DISABLED", + "value": 11 + }, + { + "name": "DISABLED_SCRIPT_UNDERPOWERED", + "value": 12 + } + ] + }, + { + "id": "relationship", + "members": [ + { + "name": "ENEMIES", + "value": 0 + }, + { + "name": "NEUTRAL", + "value": 1 + }, + { + "name": "ALLIES", + "value": 2 + } + ] + }, + { + "id": "weapon_affects", + "members": [ + { + "name": "SELF", + "value": 0 + }, + { + "name": "ALLIES", + "value": 1 + }, + { + "name": "ENEMIES", + "value": 2 + }, + { + "name": "NEUTRALS", + "value": 3 + }, + { + "name": "SUICIDE", + "value": 4 + }, + { + "name": "NOT_SIMILAR", + "value": 5 + }, + { + "name": "NOT_AIRBORNE", + "value": 6 + } + ] + }, { "id": "terrain_class", "members": [ diff --git a/crates/schema/src/lib.rs b/crates/schema/src/lib.rs index bc551b3..8c46eb7 100644 --- a/crates/schema/src/lib.rs +++ b/crates/schema/src/lib.rs @@ -193,6 +193,10 @@ pub enum ValueType { QuotedString, /// A list of ASCII strings (variadic). AsciiStringList, + /// A W3D model asset name, backed by indexed `.w3d` files. + W3dModel, + /// A bone, subobject, mesh, or other member of a W3D model asset. + W3dModelMember, /// `R:r G:g B:b [A:a]` color. Color, /// `X:x Y:y` coordinate. @@ -212,14 +216,61 @@ pub enum ValueType { /// A fixed sequence of individually-typed tokens, for engine parse /// functions that consume several tokens in order (e.g. Armor /// coefficients: `Armor = `, or WeaponSet's - /// `Weapon = `). Each listed token is required; - /// tokens beyond the list are ignored (lenient). + /// `Weapon = `). Each listed token is required. A + /// trailing BitFlags element consumes all remaining tokens. TokenList { tokens: Vec }, + /// A single token with a literal prefix and colon before the typed value + /// (e.g. `PSys:` or `RandomBone:`). + Prefixed { + prefix: String, + value_type: Box, + }, + /// One of several value shapes accepted by the same parser. + OneOf { variants: Vec }, /// Anything we could not map precisely; treated leniently (token soup). /// Carries the originating parse-fn so it can be refined later. Unknown { parse_fn: String }, } +impl ValueType { + pub fn first_prefix(&self) -> Option<&str> { + match self { + ValueType::Prefixed { prefix, .. } => Some(prefix), + ValueType::TokenList { tokens } => tokens.first().and_then(ValueType::first_prefix), + _ => None, + } + } + + pub fn variant_for_first_token(&self, first_token: Option<&str>) -> Option<&ValueType> { + let ValueType::OneOf { variants } = self else { + return Some(self); + }; + let actual = first_token.and_then(|t| t.split_once(':').map(|(prefix, _)| prefix)); + actual + .and_then(|actual| { + variants.iter().find(|variant| { + variant + .first_prefix() + .is_some_and(|prefix| prefix.eq_ignore_ascii_case(actual)) + }) + }) + .or_else(|| variants.first()) + } + + /// The value type consumed at a token position. A trailing bitflag type + /// represents the variable-length mask accepted by `INI::parseBitString32`. + pub fn token_type_at(&self, index: usize) -> Option<&ValueType> { + let ValueType::TokenList { tokens } = self else { + return Some(self); + }; + tokens.get(index).or_else(|| { + tokens + .last() + .filter(|ty| matches!(ty, ValueType::BitFlags { .. })) + }) + } +} + /// The kind of named definition a reference points at (or a block defines). #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] @@ -240,6 +291,8 @@ pub enum RefKind { MappedImage, Anim2D, PlayerTemplate, + EvaEvent, + CrateData, /// A named audio event (`AudioEvent` / `DialogEvent` / `MusicTrack`). AudioEvent, } @@ -321,6 +374,8 @@ impl<'a> SchemaIndex<'a> { #[cfg(test)] mod tests { + use std::collections::{BTreeSet, HashSet}; + use super::*; #[test] @@ -371,4 +426,1166 @@ mod tests { "ActiveBody module missing" ); } + + fn contains(ty: &ValueType, predicate: fn(&ValueType) -> bool) -> bool { + predicate(ty) + || match ty { + ValueType::TokenList { tokens } => tokens.iter().any(|ty| contains(ty, predicate)), + ValueType::Prefixed { value_type, .. } => contains(value_type, predicate), + ValueType::OneOf { variants } => variants.iter().any(|ty| contains(ty, predicate)), + _ => false, + } + } + + fn visit_sub_block_fields(sub_blocks: &[SubBlock], visit: &mut impl FnMut(&Field)) { + for sub_block in sub_blocks { + sub_block.fields.iter().for_each(&mut *visit); + visit_sub_block_fields(&sub_block.sub_blocks, visit); + } + } + + fn visit_sub_blocks(sub_blocks: &[SubBlock], visit: &mut impl FnMut(&SubBlock)) { + for sub_block in sub_blocks { + visit(sub_block); + visit_sub_blocks(&sub_block.sub_blocks, visit); + } + } + + fn collect_fields<'a>( + owner: &str, + fields: &'a [Field], + sub_blocks: &'a [SubBlock], + out: &mut Vec<(String, &'a Field)>, + ) { + out.extend( + fields + .iter() + .map(|field| (format!("{owner}.{}", field.name), field)), + ); + for sub_block in sub_blocks { + collect_fields( + &format!("{owner}/{}", sub_block.keyword), + &sub_block.fields, + &sub_block.sub_blocks, + out, + ); + } + } + + fn module_fields(schema: &Schema) -> Vec<(String, &Field)> { + let mut out = Vec::new(); + for module in &schema.modules { + collect_fields(&module.name, &module.fields, &module.sub_blocks, &mut out); + } + out + } + + fn module_field<'a>(schema: &'a Schema, module: &str, field: &str) -> &'a Field { + schema + .index() + .module(module) + .unwrap_or_else(|| panic!("module {module} missing")) + .fields + .iter() + .find(|candidate| candidate.name == field) + .unwrap_or_else(|| panic!("{module}.{field} missing")) + } + + fn sub_block<'a>(schema: &'a Schema, module: &str, keyword: &str) -> &'a SubBlock { + schema + .index() + .module(module) + .unwrap_or_else(|| panic!("module {module} missing")) + .sub_blocks + .iter() + .find(|candidate| candidate.keyword == keyword) + .unwrap_or_else(|| panic!("{module}/{keyword} missing")) + } + + fn reference(ref_kind: RefKind) -> ValueType { + ValueType::Reference { ref_kind } + } + + fn reference_list(ref_kind: RefKind) -> ValueType { + ValueType::ReferenceList { ref_kind } + } + + fn enum_type(value_set: &str) -> ValueType { + ValueType::Enum { + value_set: value_set.into(), + } + } + + fn bit_flags(value_set: &str) -> ValueType { + ValueType::BitFlags { + value_set: value_set.into(), + } + } + + fn prefixed(prefix: &str, value_type: ValueType) -> ValueType { + ValueType::Prefixed { + prefix: prefix.into(), + value_type: Box::new(value_type), + } + } + + fn token_list(tokens: Vec) -> ValueType { + ValueType::TokenList { tokens } + } + + fn assert_parser_contract( + schema: &Schema, + parse_fn: &str, + expected_count: usize, + expected_type: &ValueType, + ) { + let matches = module_fields(schema) + .into_iter() + .filter(|(_, field)| field.parse_fn == parse_fn) + .collect::>(); + assert_eq!(matches.len(), expected_count, "{parse_fn} occurrence count"); + for (path, field) in matches { + assert_eq!( + &field.value_type, expected_type, + "{path} disagrees with {parse_fn}" + ); + } + } + + fn assert_unique(owner: &str, names: impl IntoIterator) { + let mut seen = HashSet::new(); + for name in names { + assert!(!name.trim().is_empty(), "{owner} contains an empty name"); + assert!( + seen.insert(name.to_ascii_lowercase()), + "duplicate {owner} entry `{name}`" + ); + } + } + + fn validate_type( + path: &str, + value_type: &ValueType, + value_sets: &HashSet<&str>, + definitions: &HashSet, + ) { + match value_type { + ValueType::Enum { value_set } | ValueType::BitFlags { value_set } => assert!( + value_sets.contains(value_set.as_str()), + "{path} uses missing value set `{value_set}`" + ), + ValueType::Reference { ref_kind } | ValueType::ReferenceList { ref_kind } => assert!( + definitions.contains(ref_kind), + "{path} references {ref_kind:?}, but no block defines it" + ), + ValueType::TokenList { tokens } => { + assert!(!tokens.is_empty(), "{path} has an empty token list"); + for (index, token) in tokens.iter().enumerate() { + validate_type(&format!("{path}[{index}]"), token, value_sets, definitions); + } + } + ValueType::Prefixed { prefix, value_type } => { + assert!(!prefix.is_empty(), "{path} has an empty prefix"); + validate_type(path, value_type, value_sets, definitions); + } + ValueType::OneOf { variants } => { + assert!(variants.len() > 1, "{path} has a pointless one_of"); + for (index, variant) in variants.iter().enumerate() { + validate_type( + &format!("{path}.variant[{index}]"), + variant, + value_sets, + definitions, + ); + } + } + ValueType::Unknown { parse_fn } => { + assert!( + !parse_fn.is_empty(), + "{path} has an untraceable unknown type" + ) + } + _ => {} + } + } + + fn validate_scope( + owner: &str, + fields: &[Field], + sub_blocks: &[SubBlock], + value_sets: &HashSet<&str>, + definitions: &HashSet, + ) { + assert_unique(owner, fields.iter().map(|field| field.name.clone())); + assert_unique( + &format!("{owner} sub-block"), + sub_blocks.iter().map(|sub_block| sub_block.keyword.clone()), + ); + for field in fields { + let path = format!("{owner}.{}", field.name); + assert!(!field.parse_fn.is_empty(), "{path} has no parse function"); + validate_type(&path, &field.value_type, value_sets, definitions); + } + for sub_block in sub_blocks { + let path = format!("{owner}/{}", sub_block.keyword); + if let Some(argument_type) = &sub_block.argument_type { + validate_type( + &format!("{path} argument"), + argument_type, + value_sets, + definitions, + ); + } + validate_scope( + &path, + &sub_block.fields, + &sub_block.sub_blocks, + value_sets, + definitions, + ); + } + } + + #[test] + fn module_fields_have_concrete_value_types() { + let schema = embedded(); + for module in &schema.modules { + let mut check = |field: &Field| { + assert!( + !contains(&field.value_type, |ty| matches!( + ty, + ValueType::Unknown { .. } + )), + "{}.{} still has an unknown value type", + module.name, + field.name + ); + }; + module.fields.iter().for_each(&mut check); + visit_sub_block_fields(&module.sub_blocks, &mut check); + visit_sub_blocks(&module.sub_blocks, &mut |sub_block| { + if let Some(argument_type) = &sub_block.argument_type { + assert!( + !contains(argument_type, |ty| matches!(ty, ValueType::Unknown { .. })), + "{}/{} argument still has an unknown value type", + module.name, + sub_block.keyword + ); + } + }); + } + } + + #[test] + fn object_backed_module_fields_are_object_references() { + let schema = embedded(); + let expected = [ + ("AssistedTargetingUpdate", "LaserFromAssisted"), + ("AssistedTargetingUpdate", "LaserToTarget"), + ("BaikonurLaunchPower", "DetonationObject"), + ("BattlePlanUpdate", "VisionObjectName"), + ("ChinookAIUpdate", "RopeName"), + ("CountermeasuresBehavior", "FlareTemplateName"), + ("DeliverPayloadAIUpdate", "PutInContainer"), + ("FlightDeckBehavior", "PayloadTemplate"), + ("GarrisonContain", "InitialRoster"), + ("GenerateMinefieldBehavior", "MineName"), + ("GenerateMinefieldBehavior", "UpgradedMineName"), + ("HelicopterSlowDeathBehavior", "BladeObjectName"), + ("HelicopterSlowDeathBehavior", "FinalRubbleObject"), + ("HelixContain", "InitialPayload"), + ("HelixContain", "PayloadTemplateName"), + ("HijackerUpdate", "ParachuteName"), + ("InternetHackContain", "InitialPayload"), + ("JetAIUpdate", "LockonCursor"), + ("MobNexusContain", "InitialPayload"), + ("OCLSpecialPower", "ReferenceObject"), + ("OverlordContain", "InitialPayload"), + ("OverlordContain", "PayloadTemplateName"), + ("ParticleUplinkCannonUpdate", "ConnectorMediumLaserName"), + ("ParticleUplinkCannonUpdate", "ConnectorIntenseLaserName"), + ("ParticleUplinkCannonUpdate", "ParticleBeamLaserName"), + ("ParticleUplinkCannonUpdate", "DamagePulseRemnantObjectName"), + ("ProductionUpdate", "QuantityModifier"), + ("RailedTransportContain", "InitialPayload"), + ("RailroadBehavior", "CarriageTemplateName"), + ("RebuildHoleBehavior", "WorkerObjectName"), + ("RebuildHoleExposeDie", "HoleName"), + ("ReplaceObjectUpgrade", "ReplaceObject"), + ("RiderChangeContain", "InitialPayload"), + ("RiderChangeContain", "Rider1"), + ("RiderChangeContain", "Rider2"), + ("RiderChangeContain", "Rider3"), + ("RiderChangeContain", "Rider4"), + ("RiderChangeContain", "Rider5"), + ("RiderChangeContain", "Rider6"), + ("RiderChangeContain", "Rider7"), + ("RiderChangeContain", "Rider8"), + ("SpawnBehavior", "SpawnTemplateName"), + ("SpecialAbilityUpdate", "SpecialObject"), + ("SpectreGunshipDeploymentUpdate", "GunshipTemplateName"), + ("SpectreGunshipUpdate", "GattlingTemplateName"), + ("ToppleUpdate", "StumpName"), + ("TransportContain", "InitialPayload"), + ("UnitCrateCollide", "UnitName"), + ] + .into_iter() + .map(|(module, field)| format!("{module}.{field}")) + .collect::>(); + let actual = module_fields(&schema) + .into_iter() + .filter(|(_, field)| { + contains(&field.value_type, |ty| { + matches!( + ty, + ValueType::Reference { + ref_kind: RefKind::Object + } | ValueType::ReferenceList { + ref_kind: RefKind::Object + } + ) + }) + }) + .map(|(path, _)| path) + .collect::>(); + + assert_eq!(actual, expected); + } + + #[test] + fn module_inventory_matches_engine_source() { + let expected = include_str!("../../../scripts/engine_modules.txt") + .trim() + .split(',') + .map(str::to_owned) + .collect::>(); + let actual = embedded() + .modules + .into_iter() + .map(|module| module.name) + .collect::>(); + + assert_eq!(actual.len(), 223); + assert_eq!(actual, expected); + } + + #[test] + fn schema_links_and_names_are_internally_consistent() { + let schema = embedded(); + assert_eq!(schema.format_version, 4); + assert!(!schema.engine_revision.is_empty()); + assert_unique( + "block", + schema.blocks.iter().map(|block| block.name.clone()), + ); + assert_unique( + "module", + schema.modules.iter().map(|module| module.name.clone()), + ); + assert_unique( + "value set", + schema + .value_sets + .iter() + .map(|value_set| value_set.id.clone()), + ); + assert_unique( + "builtin", + schema + .builtins + .iter() + .map(|builtin| format!("{:?}:{}", builtin.ref_kind, builtin.name)), + ); + + let value_sets = schema + .value_sets + .iter() + .map(|value_set| value_set.id.as_str()) + .collect::>(); + let definitions = schema + .blocks + .iter() + .filter_map(|block| block.defines) + .chain(schema.builtins.iter().map(|builtin| builtin.ref_kind)) + .collect::>(); + + for value_set in &schema.value_sets { + assert!(!value_set.members.is_empty(), "{} is empty", value_set.id); + assert_unique( + &format!("{} member", value_set.id), + value_set.members.iter().map(|member| member.name.clone()), + ); + } + for block in &schema.blocks { + assert!( + !block.parse_fn.is_empty(), + "{} has no parse function", + block.name + ); + assert!( + block.defines.is_none() || block.named, + "anonymous block {} cannot define a symbol", + block.name + ); + validate_scope( + &block.name, + &block.fields, + &block.sub_blocks, + &value_sets, + &definitions, + ); + } + for module in &schema.modules { + assert!( + !module.interfaces.is_empty(), + "{} has no interface", + module.name + ); + assert_unique( + &format!("{} interface", module.name), + module.interfaces.iter().cloned(), + ); + validate_scope( + &module.name, + &module.fields, + &module.sub_blocks, + &value_sets, + &definitions, + ); + } + + let module_interfaces = schema + .modules + .iter() + .flat_map(|module| module.interfaces.iter().map(String::as_str)) + .collect::>(); + let accepted_interfaces = schema + .blocks + .iter() + .flat_map(|block| &block.module_slots) + .flat_map(|slot| slot.accepts.iter().map(String::as_str)) + .collect::>(); + assert_eq!(module_interfaces, accepted_interfaces); + for block in &schema.blocks { + assert_unique( + &format!("{} module slot", block.name), + block.module_slots.iter().map(|slot| slot.keyword.clone()), + ); + for slot in &block.module_slots { + assert!( + !slot.accepts.is_empty(), + "{}.{} accepts nothing", + block.name, + slot.keyword + ); + assert!( + slot.accepts + .iter() + .all(|interface| module_interfaces.contains(interface.as_str())), + "{}.{} accepts an unknown interface", + block.name, + slot.keyword + ); + } + } + } + + #[test] + fn common_module_parsers_keep_their_engine_types() { + let schema = embedded(); + let contracts = [ + ("INI::parseAccelerationReal", 1, ValueType::Acceleration), + ("INI::parseAngleReal", 356, ValueType::AngleReal), + ("INI::parseAngularVelocityReal", 74, ValueType::AngleReal), + ("INI::parseBool", 606, ValueType::Bool), + ("INI::parseColorInt", 7, ValueType::Color), + ("INI::parseCoord3D", 9, ValueType::Coord3D), + ("INI::parseDurationReal", 31, ValueType::Duration), + ("INI::parseDurationUnsignedInt", 379, ValueType::Duration), + ("INI::parseInt", 94, ValueType::Int), + ("INI::parsePercentToReal", 64, ValueType::Percent), + ("INI::parsePositiveNonZeroReal", 12, ValueType::PositiveReal), + ("INI::parseReal", 359, ValueType::Real), + ("INI::parseRGBColor", 3, ValueType::Color), + ("INI::parseUnsignedInt", 27, ValueType::UInt), + ("INI::parseVelocityReal", 39, ValueType::Velocity), + ]; + + for (parse_fn, count, value_type) in contracts { + assert_parser_contract(&schema, parse_fn, count, &value_type); + } + for (parse_fn, count, value_type) in [ + ( + "INI::parseAudioEventRTS", + 67, + reference(RefKind::AudioEvent), + ), + ("INI::parseFXList", 89, reference(RefKind::FxList)), + ( + "INI::parseObjectCreationList", + 20, + reference(RefKind::ObjectCreationList), + ), + ( + "INI::parseParticleSystemTemplate", + 31, + reference(RefKind::ParticleSystem), + ), + ("INI::parseScience", 19, reference(RefKind::Science)), + ( + "INI::parseSpecialPowerTemplate", + 18, + reference(RefKind::SpecialPower), + ), + ("INI::parseWeaponTemplate", 22, reference(RefKind::Weapon)), + ] { + assert_parser_contract(&schema, parse_fn, count, &value_type); + } + let ascii_vectors = module_fields(&schema) + .into_iter() + .filter(|(_, field)| field.parse_fn == "INI::parseAsciiStringVector") + .map(|(_, field)| field.value_type.clone()) + .collect::>(); + assert_eq!(ascii_vectors.len(), 91); + assert_eq!( + ascii_vectors + .iter() + .filter(|value_type| **value_type == reference_list(RefKind::Upgrade)) + .count(), + 84 + ); + assert_eq!( + ascii_vectors + .iter() + .filter(|value_type| **value_type == ValueType::AsciiStringList) + .count(), + 7 + ); + let appended_ascii_vectors = module_fields(&schema) + .into_iter() + .filter(|(_, field)| field.parse_fn == "INI::parseAsciiStringVectorAppend") + .map(|(_, field)| field.value_type.clone()) + .collect::>(); + assert_eq!(appended_ascii_vectors.len(), 17); + assert_eq!( + appended_ascii_vectors + .iter() + .filter(|value_type| **value_type == reference_list(RefKind::Object)) + .count(), + 4 + ); + assert_eq!( + appended_ascii_vectors + .iter() + .filter(|value_type| **value_type == ValueType::AsciiStringList) + .count(), + 13 + ); + } + + #[test] + fn custom_module_parser_inventory_is_explicit() { + let expected = [ + "BoneFXUpdateModuleData::parseFXList", + "BoneFXUpdateModuleData::parseObjectCreationList", + "BoneFXUpdateModuleData::parseParticleSystem", + "CreateCrateDieModuleData::parseCrateData", + "Eva::parseEvaMessageFromIni", + "parseAngleFX", + "parseAnimation", + "parseAppendQuantityModifier", + "parseAsciiStringLC", + "parseBoneNameKey", + "parseBountyUpgradePair", + "parseCashHackUpgradePair", + "parseFactionObjectCreationList", + "parseFrictionPerSec", + "parseFX", + "parseHeightToSpeed", + "parseInitialPayload", + "parseInitialRoster", + "parseLowercaseNameKey", + "parseOCL", + "parseOCLUpgradePair", + "parseParticleSysBone", + "parseRealRange", + "parseRiderInfo", + "parseRunwayStrip", + "parseShowHideSubObject", + "parseTWS", + "parseUpgradePair", + "parseWeapon", + "parseWeaponBoneName", + "TransitionDamageFXModuleData::parseFXList", + "TransitionDamageFXModuleData::parseObjectCreationList", + "TransitionDamageFXModuleData::parseParticleSystem", + "TurretAIData::parseTurretSweep", + "TurretAIData::parseTurretSweepSpeed", + "W3DModelDrawModuleData::parseConditionState", + ] + .into_iter() + .collect::>(); + let schema = embedded(); + let actual = module_fields(&schema) + .into_iter() + .map(|(_, field)| field.parse_fn.as_str()) + .filter(|parse_fn| { + !parse_fn.starts_with("INI::") + && !parse_fn.ends_with("::parseFromINI") + && !parse_fn.ends_with("::parseSingleBitFromINI") + }) + .collect::>(); + + assert_eq!(actual, expected); + } + + #[test] + fn structured_custom_parsers_match_engine_token_order() { + let schema = embedded(); + assert_parser_contract( + &schema, + "parseWeaponBoneName", + 165, + &token_list(vec![enum_type("weapon_slot"), ValueType::W3dModelMember]), + ); + assert_parser_contract( + &schema, + "parseParticleSysBone", + 33, + &token_list(vec![ + ValueType::W3dModelMember, + reference(RefKind::ParticleSystem), + ]), + ); + assert_parser_contract( + &schema, + "parseRealRange", + 33, + &token_list(vec![ValueType::Real, ValueType::Real]), + ); + assert_parser_contract( + &schema, + "TurretAIData::parseTurretSweep", + 30, + &token_list(vec![enum_type("weapon_slot"), ValueType::AngleReal]), + ); + assert_parser_contract( + &schema, + "TurretAIData::parseTurretSweepSpeed", + 30, + &token_list(vec![enum_type("weapon_slot"), ValueType::Real]), + ); + assert_parser_contract(&schema, "parseTWS", 30, &bit_flags("weapon_slot")); + assert_parser_contract( + &schema, + "parseInitialPayload", + 7, + &token_list(vec![reference(RefKind::Object), ValueType::Int]), + ); + assert_parser_contract( + &schema, + "parseInitialRoster", + 1, + &token_list(vec![reference(RefKind::Object), ValueType::Int]), + ); + assert_parser_contract( + &schema, + "parseAppendQuantityModifier", + 1, + &token_list(vec![reference(RefKind::Object), ValueType::Int]), + ); + assert_parser_contract( + &schema, + "parseRiderInfo", + 8, + &token_list(vec![ + reference(RefKind::Object), + enum_type("model_condition"), + enum_type("weapon_set_conditions"), + enum_type("object_status"), + reference(RefKind::CommandSet), + enum_type("locomotor_set"), + ]), + ); + assert_parser_contract(&schema, "parseRunwayStrip", 4, &ValueType::AsciiStringList); + assert_parser_contract(&schema, "parseFrictionPerSec", 8, &ValueType::Real); + assert_parser_contract(&schema, "parseHeightToSpeed", 2, &ValueType::Real); + assert_parser_contract( + &schema, + "Eva::parseEvaMessageFromIni", + 2, + &reference(RefKind::EvaEvent), + ); + assert_parser_contract( + &schema, + "CreateCrateDieModuleData::parseCrateData", + 1, + &reference(RefKind::CrateData), + ); + assert_parser_contract( + &schema, + "parseAngleFX", + 1, + &token_list(vec![ValueType::AngleReal, reference(RefKind::FxList)]), + ); + assert_parser_contract( + &schema, + "parseUpgradePair", + 2, + &token_list(vec![ + prefixed("UpgradeType", reference(RefKind::Upgrade)), + prefixed("Boost", ValueType::Int), + ]), + ); + assert_parser_contract( + &schema, + "parseCashHackUpgradePair", + 1, + &token_list(vec![reference(RefKind::Science), ValueType::Int]), + ); + assert_parser_contract( + &schema, + "parseBountyUpgradePair", + 1, + &token_list(vec![reference(RefKind::Science), ValueType::Percent]), + ); + assert_parser_contract( + &schema, + "parseOCLUpgradePair", + 1, + &token_list(vec![ + reference(RefKind::Science), + reference(RefKind::ObjectCreationList), + ]), + ); + assert_parser_contract( + &schema, + "parseFactionObjectCreationList", + 1, + &token_list(vec![ + prefixed("Faction", reference(RefKind::PlayerTemplate)), + prefixed("OCL", reference(RefKind::ObjectCreationList)), + ]), + ); + } + + #[test] + fn inherited_draw_damage_and_death_tables_keep_their_shapes() { + let schema = embedded(); + assert_parser_contract(&schema, "parseBoneNameKey", 132, &ValueType::W3dModelMember); + assert_parser_contract( + &schema, + "parseShowHideSubObject", + 66, + &ValueType::W3dModelMember, + ); + assert_parser_contract(&schema, "parseAnimation", 66, &ValueType::AsciiString); + assert_parser_contract( + &schema, + "parseLowercaseNameKey", + 66, + &ValueType::AsciiString, + ); + + for (parse_fn, prefix, ref_kind) in [ + ( + "BoneFXUpdateModuleData::parseFXList", + "FXList", + RefKind::FxList, + ), + ( + "BoneFXUpdateModuleData::parseObjectCreationList", + "OCL", + RefKind::ObjectCreationList, + ), + ( + "BoneFXUpdateModuleData::parseParticleSystem", + "PSys", + RefKind::ParticleSystem, + ), + ] { + assert_parser_contract( + &schema, + parse_fn, + 32, + &token_list(vec![ + prefixed("Bone", ValueType::W3dModelMember), + prefixed("OnlyOnce", ValueType::Bool), + ValueType::Duration, + ValueType::Duration, + prefixed(prefix, reference(ref_kind)), + ]), + ); + } + + for (parse_fn, prefix, ref_kind) in [ + ( + "TransitionDamageFXModuleData::parseFXList", + "FXList", + RefKind::FxList, + ), + ( + "TransitionDamageFXModuleData::parseObjectCreationList", + "OCL", + RefKind::ObjectCreationList, + ), + ( + "TransitionDamageFXModuleData::parseParticleSystem", + "PSys", + RefKind::ParticleSystem, + ), + ] { + assert_parser_contract( + &schema, + parse_fn, + 36, + &ValueType::OneOf { + variants: vec![ + token_list(vec![ + prefixed("Bone", ValueType::AsciiString), + prefixed("RandomBone", ValueType::Bool), + prefixed(prefix, reference(ref_kind)), + ]), + token_list(vec![ + prefixed("Loc", ValueType::AsciiString), + prefixed("Y", ValueType::Real), + prefixed("Z", ValueType::Real), + prefixed(prefix, reference(ref_kind)), + ]), + ], + }, + ); + } + + let feedback_slots = module_fields(&schema) + .into_iter() + .filter(|(_, field)| field.name == "ProjectileBoneFeedbackEnabledSlots") + .collect::>(); + assert_eq!(feedback_slots.len(), 11); + assert!(feedback_slots + .iter() + .all(|(_, field)| field.value_type == bit_flags("weapon_slot"))); + + let slow_death_modules = [ + "BattleBusSlowDeathBehavior", + "HelicopterSlowDeathBehavior", + "JetSlowDeathBehavior", + "NeutronMissileSlowDeathBehavior", + "SlowDeathBehavior", + ]; + for module in slow_death_modules { + for (field, ref_kind) in [ + ("FX", RefKind::FxList), + ("OCL", RefKind::ObjectCreationList), + ("Weapon", RefKind::Weapon), + ] { + assert_eq!( + module_field(&schema, module, field).value_type, + token_list(vec![ + enum_type("slow_death_phase"), + reference_list(ref_kind), + ]), + "{module}.{field}" + ); + } + } + for (field, ref_kind) in [ + ("FX", RefKind::FxList), + ("OCL", RefKind::ObjectCreationList), + ("Weapon", RefKind::Weapon), + ] { + assert_eq!( + module_field(&schema, "InstantDeathBehavior", field).value_type, + reference_list(ref_kind), + "InstantDeathBehavior.{field}" + ); + } + } + + #[test] + fn source_structures_and_disabled_rows_stay_pinned() { + let schema = embedded(); + + for (module, field) in [ + ("BoneFXDamage", "DamageTypes"), + ("TransitionDamageFX", "DamageTypes"), + ("EMPUpdate", "SpinRateMax"), + ("ParkingPlaceBehavior", "ExtraHealAmount4Helicopters"), + ("ParkingPlaceBehavior", "TimeForFullHeal"), + ("RadiusDecalUpdate", "DeliveryDecal"), + ("RadiusDecalUpdate", "DeliveryDecalRadius"), + ] { + assert!( + schema + .index() + .module(module) + .unwrap() + .fields + .iter() + .all(|candidate| candidate.name != field), + "commented-out engine row {module}.{field} leaked into the schema" + ); + } + assert_eq!( + module_field(&schema, "HealContain", "TimeForFullHeal").value_type, + ValueType::Duration + ); + assert_eq!( + module_field(&schema, "FireWeaponWhenDamagedBehavior", "DamageTypes").value_type, + bit_flags("damage_type") + ); + + let turret_modules = schema + .modules + .iter() + .filter(|module| { + module + .sub_blocks + .iter() + .any(|sub_block| sub_block.keyword == "Turret") + }) + .collect::>(); + assert_eq!(turret_modules.len(), 15); + for module in turret_modules { + assert!(module.fields.iter().all(|field| field.name != "Turret")); + assert!(module.fields.iter().all(|field| field.name != "AltTurret")); + assert!(module + .sub_blocks + .iter() + .any(|sub_block| sub_block.keyword == "AltTurret")); + } + + let decal_fields = [ + ("Texture", ValueType::AsciiString), + ("Style", bit_flags("shadow_type")), + ("OpacityMin", ValueType::Percent), + ("OpacityMax", ValueType::Percent), + ("OpacityThrobTime", ValueType::Duration), + ("Color", ValueType::Color), + ("OnlyVisibleToOwningPlayer", ValueType::Bool), + ]; + for (module, keyword) in [ + ("DeliverPayloadAIUpdate", "DeliveryDecal"), + ("DynamicShroudClearingRangeUpdate", "GridDecalTemplate"), + ("NeutronMissileUpdate", "DeliveryDecal"), + ("SpectreGunshipUpdate", "AttackAreaDecal"), + ("SpectreGunshipUpdate", "TargetingReticleDecal"), + ] { + let actual = sub_block(&schema, module, keyword) + .fields + .iter() + .map(|field| (field.name.as_str(), field.value_type.clone())) + .collect::>(); + assert_eq!(actual, decal_fields, "{module}/{keyword}"); + } + let radius = schema.index().module("RadiusDecalUpdate").unwrap(); + assert!(radius.fields.is_empty()); + assert!(radius.sub_blocks.is_empty()); + + let ai_data = schema.index().block("AIData").unwrap(); + let build_list = ai_data + .sub_blocks + .iter() + .find(|sub_block| sub_block.keyword == "SkirmishBuildList") + .unwrap(); + let structure = build_list + .sub_blocks + .iter() + .find(|sub_block| sub_block.keyword == "Structure") + .unwrap(); + assert_eq!(structure.argument_type, Some(reference(RefKind::Object))); + + assert_eq!( + schema.index().block("EvaEvent").unwrap().defines, + Some(RefKind::EvaEvent) + ); + assert_eq!( + schema.index().block("CrateData").unwrap().defines, + Some(RefKind::CrateData) + ); + } + + #[test] + fn source_enum_sets_keep_their_exact_members() { + let schema = embedded(); + for (id, expected) in [ + ( + "disabled_type", + &[ + "DEFAULT", + "DISABLED_HACKED", + "DISABLED_EMP", + "DISABLED_HELD", + "DISABLED_PARALYZED", + "DISABLED_UNMANNED", + "DISABLED_UNDERPOWERED", + "DISABLED_FREEFALL", + "DISABLED_AWESTRUCK", + "DISABLED_BRAINWASHED", + "DISABLED_SUBDUED", + "DISABLED_SCRIPT_DISABLED", + "DISABLED_SCRIPT_UNDERPOWERED", + ][..], + ), + ("relationship", &["ENEMIES", "NEUTRAL", "ALLIES"]), + ( + "weapon_affects", + &[ + "SELF", + "ALLIES", + "ENEMIES", + "NEUTRALS", + "SUICIDE", + "NOT_SIMILAR", + "NOT_AIRBORNE", + ], + ), + ] { + let actual = schema + .index() + .value_set(id) + .unwrap() + .members + .iter() + .map(|member| member.name.as_str()) + .collect::>(); + assert_eq!(actual, expected, "{id}"); + } + } + + #[test] + fn ascii_backed_engine_names_keep_their_semantic_types() { + let schema = embedded(); + for (module, field, value_type) in [ + ("ArmorUpgrade", "FXListUpgrade", reference(RefKind::FxList)), + ( + "BunkerBusterBehavior", + "UpgradeRequired", + reference(RefKind::Upgrade), + ), + ( + "PropagandaTowerBehavior", + "UpgradeRequired", + reference(RefKind::Upgrade), + ), + ( + "CommandSetUpgrade", + "CommandSet", + reference(RefKind::CommandSet), + ), + ( + "CommandSetUpgrade", + "CommandSetAlt", + reference(RefKind::CommandSet), + ), + ( + "CommandSetUpgrade", + "TriggerAlt", + reference(RefKind::Upgrade), + ), + ( + "FlammableUpdate", + "BurningSoundName", + reference(RefKind::AudioEvent), + ), + ( + "GrantScienceUpgrade", + "GrantScience", + reference(RefKind::Science), + ), + ( + "GrantUpgradeCreate", + "UpgradeToGrant", + reference(RefKind::Upgrade), + ), + ( + "StructureToppleUpdate", + "CrushingWeaponName", + reference(RefKind::Weapon), + ), + ("UpgradeDie", "UpgradeToRemove", reference(RefKind::Upgrade)), + ( + "ChinookAIUpdate", + "RotorWashParticleSystem", + reference(RefKind::ParticleSystem), + ), + ( + "LaserUpdate", + "MuzzleParticleSystem", + reference(RefKind::ParticleSystem), + ), + ( + "LaserUpdate", + "TargetParticleSystem", + reference(RefKind::ParticleSystem), + ), + ( + "SlavedUpdate", + "RepairWeldingSys", + reference(RefKind::ParticleSystem), + ), + ("W3DPropDraw", "ModelName", ValueType::W3dModel), + ("W3DTreeDraw", "ModelName", ValueType::W3dModel), + ("W3DTreeDraw", "StumpName", ValueType::W3dModel), + ] { + assert_eq!( + module_field(&schema, module, field).value_type, + value_type, + "{module}.{field}" + ); + } + + let battle_plan_audio = [ + "BombardmentPlanUnpackSoundName", + "BombardmentPlanPackSoundName", + "BombardmentAnnouncementName", + "SearchAndDestroyPlanUnpackSoundName", + "SearchAndDestroyPlanIdleLoopSoundName", + "SearchAndDestroyPlanPackSoundName", + "SearchAndDestroyAnnouncementName", + "HoldTheLinePlanUnpackSoundName", + "HoldTheLinePlanPackSoundName", + "HoldTheLineAnnouncementName", + ]; + for field in battle_plan_audio { + assert_eq!( + module_field(&schema, "BattlePlanUpdate", field).value_type, + reference(RefKind::AudioEvent), + "BattlePlanUpdate.{field}" + ); + } + + let animations = module_fields(&schema) + .into_iter() + .filter(|(_, field)| field.name == "ExecuteAnimation") + .collect::>(); + assert_eq!(animations.len(), 16); + assert!(animations + .iter() + .all(|(_, field)| field.value_type == reference(RefKind::Anim2D))); + + for module in [ + "W3DOverlordTruckDraw", + "W3DPoliceCarDraw", + "W3DTankTruckDraw", + "W3DTruckDraw", + ] { + for field in ["Dust", "DirtSpray", "PowerslideSpray"] { + assert_eq!( + module_field(&schema, module, field).value_type, + reference(RefKind::ParticleSystem), + "{module}.{field}" + ); + } + } + for module in ["W3DOverlordTankDraw", "W3DTankDraw", "W3DTankTruckDraw"] { + for field in ["TreadDebrisLeft", "TreadDebrisRight"] { + assert_eq!( + module_field(&schema, module, field).value_type, + reference(RefKind::ParticleSystem), + "{module}.{field}" + ); + } + } + } } diff --git a/crates/server/src/backend.rs b/crates/server/src/backend.rs index 5cebc7b..f1cfc4f 100644 --- a/crates/server/src/backend.rs +++ b/crates/server/src/backend.rs @@ -18,7 +18,8 @@ use tower_lsp::lsp_types::*; use tower_lsp::{jsonrpc::Result, Client, LanguageServer}; use zerosyntax_analysis::diagnostics::DiagnosticsCache; use zerosyntax_analysis::index::{ - definitions_in, module_tags_in, references_in, Definition, ReferenceSite, WorkspaceIndex, + definitions_in, module_tags_in, references_in, Definition, ModelAsset, ReferenceSite, + WorkspaceIndex, }; use zerosyntax_analysis::nav::{definition_at, hover_at, reference_at, HoverInfo}; use zerosyntax_analysis::{actions, completion, diagnostics, format, outline, semantic, Analyzer}; @@ -74,6 +75,9 @@ pub struct Backend { /// Whether the client supports snippet insertText (tab-stops, placeholders). /// Captured at `initialize` from the client's completion-item capabilities. snippet_support: OnceLock, + /// Whether the client supports `window/workDoneProgress` (the scan + /// spinner). Captured at `initialize`. + progress_support: OnceLock, /// Monotonic id source for semantic-token results (delta bookkeeping). semantic_result_id: std::sync::atomic::AtomicU64, } @@ -83,6 +87,7 @@ type ScanEntry = ( Vec, Vec, Vec<(String, String)>, + Vec, Option>, ); @@ -210,11 +215,16 @@ fn big_entries(path: &Path) -> std::io::Result> { Ok(entries) } -fn read_big_entry(path: &Path, entry: &BigEntry) -> Option { +fn read_big_entry_bytes(path: &Path, entry: &BigEntry) -> Option> { let mut file = std::fs::File::open(path).ok()?; file.seek(SeekFrom::Start(entry.offset)).ok()?; let mut bytes = vec![0; entry.size]; file.read_exact(&mut bytes).ok()?; + Some(bytes) +} + +fn read_big_entry(path: &Path, entry: &BigEntry) -> Option { + let bytes = read_big_entry_bytes(path, entry)?; Some(String::from_utf8_lossy(&bytes).into_owned()) } @@ -225,31 +235,176 @@ fn big_uri(path: &Path, entry: &str) -> String { uri.to_string() } +fn file_stem_str(path: &str) -> String { + let file_name = path.rsplit(['/', '\\']).next().unwrap_or(path); + file_name + .rsplit_once('.') + .map(|(stem, _)| stem) + .unwrap_or(file_name) + .to_string() +} + +fn parse_w3d_models(bytes: &[u8], fallback_name: &str) -> Vec { + let mut names = Vec::new(); + let mut members = Vec::new(); + if !fallback_name.is_empty() { + names.push(fallback_name.to_string()); + } + walk_w3d_chunks(bytes, 0, bytes.len(), 0, &mut |kind, payload| match kind { + 0x0000_001F if payload.len() >= 40 => { + push_name(&mut members, read_fixed_name(&payload[8..24])); + push_name(&mut names, read_fixed_name(&payload[24..40])); + } + // HIERARCHY_HEADER, EMITTER_HEADER, AGGREGATE_HEADER: Version + Name[16]. + 0x0000_0101 | 0x0000_0501 | 0x0000_0601 if payload.len() >= 20 => { + push_name(&mut names, read_fixed_name(&payload[4..20])); + } + 0x0000_0102 => { + for pivot in payload.chunks_exact(60) { + push_name(&mut members, read_fixed_name(&pivot[..16])); + } + } + 0x0000_0701 if payload.len() >= 40 => { + push_name(&mut names, read_fixed_name(&payload[8..24])); + push_name(&mut names, read_fixed_name(&payload[24..40])); + } + 0x0000_0704 if payload.len() >= 36 => { + push_name(&mut members, read_fixed_name(&payload[4..36])); + } + 0x0000_0740 if payload.len() >= 40 => { + push_name(&mut members, read_fixed_name(&payload[8..40])); + } + 0x0000_0750 if payload.len() >= 48 => { + push_name(&mut members, read_fixed_name(&payload[16..48])) + } + _ => {} + }); + dedup_case_insensitive(&mut names); + dedup_case_insensitive(&mut members); + names + .into_iter() + .filter(|name| !name.is_empty()) + .map(|name| ModelAsset { + name, + members: members.clone(), + }) + .collect() +} + +/// Real W3D files nest at most a handful of levels; the cap only guards +/// against corrupt or hostile files driving unbounded recursion. +const MAX_W3D_CHUNK_DEPTH: usize = 16; + +fn walk_w3d_chunks( + bytes: &[u8], + mut pos: usize, + end: usize, + depth: usize, + f: &mut impl FnMut(u32, &[u8]), +) { + if depth > MAX_W3D_CHUNK_DEPTH { + return; + } + while pos + 8 <= end && pos + 8 <= bytes.len() { + let kind = u32::from_le_bytes(bytes[pos..pos + 4].try_into().unwrap()); + let size_raw = u32::from_le_bytes(bytes[pos + 4..pos + 8].try_into().unwrap()); + let has_children = (size_raw & 0x8000_0000) != 0 || is_w3d_container(kind); + let size = (size_raw & 0x7fff_ffff) as usize; + let payload_start = pos + 8; + let Some(payload_end) = payload_start.checked_add(size) else { + break; + }; + if payload_end > end || payload_end > bytes.len() { + break; + } + let payload = &bytes[payload_start..payload_end]; + f(kind, payload); + if has_children { + walk_w3d_chunks(bytes, payload_start, payload_end, depth + 1, f); + } + pos = payload_end; + } +} + +fn is_w3d_container(kind: u32) -> bool { + // MESH, HIERARCHY, EMITTER, AGGREGATE, HLOD, HLOD_LOD_ARRAY, + // HLOD_AGGREGATE_ARRAY (w3d_file.h; the MSB size flag is the primary + // signal, these are fallbacks for files that omit it). + matches!( + kind, + 0x0000_0000 + | 0x0000_0100 + | 0x0000_0500 + | 0x0000_0600 + | 0x0000_0700 + | 0x0000_0702 + | 0x0000_0705 + ) +} + +fn read_fixed_name(bytes: &[u8]) -> &str { + let end = bytes.iter().position(|b| *b == 0).unwrap_or(bytes.len()); + std::str::from_utf8(&bytes[..end]).unwrap_or("").trim() +} + +fn push_name(out: &mut Vec, name: &str) { + if name.is_empty() { + return; + } + out.push(name.to_string()); + if let Some((_, short)) = name.rsplit_once('.') { + if !short.is_empty() { + out.push(short.to_string()); + } + } +} + +fn dedup_case_insensitive(values: &mut Vec) { + let mut seen = std::collections::HashSet::new(); + values.retain(|value| seen.insert(value.to_ascii_lowercase())); +} + fn scan_big(analyzer: &Analyzer, path: &Path) -> Vec { let mut out = Vec::new(); let Ok(entries) = big_entries(path) else { return out; }; for entry in entries { - if !entry.name.ends_with(".ini") && !entry.name.ends_with(".INI") { - continue; - } - let Some(text) = read_big_entry(path, &entry) else { - continue; - }; let file = big_uri(path, &entry.name); - let parse = analyzer.parse(&text); - let defs = definitions_in(analyzer, &parse, &file); - let refs = references_in(analyzer, &parse); - let tags = module_tags_in(analyzer, &parse); - out.push((file, defs, refs, tags, Some(Arc::from(text)))); + if entry.name.ends_with(".ini") || entry.name.ends_with(".INI") { + let Some(text) = read_big_entry(path, &entry) else { + continue; + }; + let parse = analyzer.parse(&text); + let defs = definitions_in(analyzer, &parse, &file); + let refs = references_in(analyzer, &parse); + let tags = module_tags_in(analyzer, &parse); + out.push((file, defs, refs, tags, Vec::new(), Some(Arc::from(text)))); + } else if entry.name.ends_with(".w3d") || entry.name.ends_with(".W3D") { + let Some(bytes) = read_big_entry_bytes(path, &entry) else { + continue; + }; + let stem = file_stem_str(&entry.name); + let models = parse_w3d_models(&bytes, &stem); + if !models.is_empty() { + out.push((file, Vec::new(), Vec::new(), Vec::new(), models, None)); + } + } } out } -/// Walk `roots` and index every `.ini` file (definitions + reference sites + module tags). -/// CPU/IO heavy — runs via `spawn_blocking` from [`Backend::scan_workspace`]. +/// Walk `roots` and index `.ini` files plus `.w3d` model assets in one call. +/// Production code goes through `collect_scan_paths` + `scan_files` so the +/// scan can report progress; this convenience wrapper serves the tests. +#[cfg(test)] fn scan_roots(analyzer: &Analyzer, roots: &[PathBuf]) -> Vec { + scan_files(analyzer, &collect_scan_paths(roots), &mut |_, _| {}) +} + +/// Phase 1 of the scan: a cheap walk collecting every indexable file +/// (`.ini` / `.big` / `.w3d`), so phase 2 can report `done/total` progress. +fn collect_scan_paths(roots: &[PathBuf]) -> Vec { let mut out = Vec::new(); for root in roots { if root @@ -257,7 +412,7 @@ fn scan_roots(analyzer: &Analyzer, roots: &[PathBuf]) -> Vec { .and_then(|e| e.to_str()) .is_some_and(|e| e.eq_ignore_ascii_case("big")) { - out.extend(scan_big(analyzer, root)); + out.push(root.clone()); continue; } for entry in walkdir::WalkDir::new(root) @@ -265,35 +420,59 @@ fn scan_roots(analyzer: &Analyzer, roots: &[PathBuf]) -> Vec { .filter_map(|e| e.ok()) { let path = entry.path(); - // Real game data mixes extension casing (`*.ini` / `*.INI`, - // e.g. the MappedImages files), so compare case-insensitively. - if !path - .extension() - .and_then(|e| e.to_str()) - .is_some_and(|e| e.eq_ignore_ascii_case("ini") || e.eq_ignore_ascii_case("big")) + let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(""); + if ext.eq_ignore_ascii_case("big") + || ext.eq_ignore_ascii_case("ini") + || ext.eq_ignore_ascii_case("w3d") { - continue; + out.push(path.to_path_buf()); } - if path - .extension() - .and_then(|e| e.to_str()) - .is_some_and(|e| e.eq_ignore_ascii_case("big")) - { - out.extend(scan_big(analyzer, path)); - continue; + } + } + out +} + +/// Phase 2 of the scan: parse/index each collected file, invoking +/// `progress(done, total)` after each one (a `.big` archive counts as one +/// unit of work regardless of how many entries it holds). +fn scan_files( + analyzer: &Analyzer, + paths: &[PathBuf], + progress: &mut impl FnMut(usize, usize), +) -> Vec { + let mut out = Vec::new(); + for (i, path) in paths.iter().enumerate() { + let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(""); + if ext.eq_ignore_ascii_case("big") { + out.extend(scan_big(analyzer, path)); + } else if ext.eq_ignore_ascii_case("ini") { + if let (Some(text), Ok(uri)) = (read_lossy(path), Url::from_file_path(path)) { + let parse = analyzer.parse(&text); + let defs = definitions_in(analyzer, &parse, uri.as_str()); + let refs = references_in(analyzer, &parse); + let tags = module_tags_in(analyzer, &parse); + out.push((uri.to_string(), defs, refs, tags, Vec::new(), None)); + } + } else if ext.eq_ignore_ascii_case("w3d") { + if let (Ok(bytes), Ok(uri)) = (std::fs::read(path), Url::from_file_path(path)) { + let stem = path + .file_stem() + .and_then(|s| s.to_str()) + .unwrap_or_default(); + let models = parse_w3d_models(&bytes, stem); + if !models.is_empty() { + out.push(( + uri.to_string(), + Vec::new(), + Vec::new(), + Vec::new(), + models, + None, + )); + } } - let Some(text) = read_lossy(path) else { - continue; - }; - let Ok(uri) = Url::from_file_path(path) else { - continue; - }; - let parse = analyzer.parse(&text); - let defs = definitions_in(analyzer, &parse, uri.as_str()); - let refs = references_in(analyzer, &parse); - let tags = module_tags_in(analyzer, &parse); - out.push((uri.to_string(), defs, refs, tags, None)); } + progress(i + 1, paths.len()); } out } @@ -315,6 +494,7 @@ impl Backend { base_roots_hint_shown: AtomicBool::new(false), client_base_ini_hint: OnceLock::new(), snippet_support: OnceLock::new(), + progress_support: OnceLock::new(), semantic_result_id: std::sync::atomic::AtomicU64::new(1), } } @@ -428,8 +608,12 @@ impl Backend { /// Best-effort scan of the workspace roots for `.ini` files to seed the /// index, so references resolve before a file is opened. The walk + /// parse runs on a blocking thread (full-mod folders take seconds); the - /// results are applied under the index lock afterwards. + /// results are applied under the index lock afterwards. Reported to the + /// client as `$/progress` (a status-bar spinner with a `done/total` + /// counter in VS Code) so users can tell "still indexing" apart from + /// "nothing was found". async fn scan_workspace(&self) { + let progress_token = self.begin_scan_progress().await; let roots = self.roots.lock().map(|r| r.clone()).unwrap_or_default(); let base_roots = self .base_roots @@ -437,17 +621,51 @@ impl Backend { .map(|r| r.clone()) .unwrap_or_default(); let analyzer = self.analyzer.clone(); - let (scanned, base_scanned) = tokio::task::spawn_blocking(move || { - ( - scan_roots(&analyzer, &roots), - scan_roots(&analyzer, &base_roots), - ) - }) - .await - .unwrap_or_default(); + // The blocking scan streams (done, total) over a channel; forward + // each update as a progress report while waiting for the results. + let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<(usize, usize)>(); + let handle = tokio::task::spawn_blocking(move || { + let workspace_paths = collect_scan_paths(&roots); + let base_paths = collect_scan_paths(&base_roots); + let total = workspace_paths.len() + base_paths.len(); + let mut done = 0; + let mut last_percent = u32::MAX; + // Throttle to whole-percent changes (plus the final count) so a + // 10k-file scan sends ~100 notifications, not 10k. + let mut progress = |_done_in_batch: usize, _batch_total: usize| { + done += 1; + let percent = (done * 100 / total.max(1)) as u32; + if percent != last_percent || done == total { + last_percent = percent; + let _ = tx.send((done, total)); + } + }; + let scanned = scan_files(&analyzer, &workspace_paths, &mut progress); + let base_scanned = scan_files(&analyzer, &base_paths, &mut progress); + (scanned, base_scanned) + }); + while let Some((done, total)) = rx.recv().await { + self.report_scan_progress(&progress_token, done, total) + .await; + } + let (scanned, base_scanned) = handle.await.unwrap_or_default(); + let base_ini_count = base_scanned + .iter() + .filter(|(_, _, _, _, models, _)| models.is_empty()) + .count(); self.base_indexed_count - .store(base_scanned.len(), Ordering::Relaxed); + .store(base_ini_count, Ordering::Relaxed); self.scan_finished.store(true, Ordering::Relaxed); + let ini_total = base_ini_count + + scanned + .iter() + .filter(|(_, _, _, _, models, _)| models.is_empty()) + .count(); + let model_total: usize = base_scanned + .iter() + .chain(scanned.iter()) + .map(|(_, _, _, _, models, _)| models.len()) + .sum(); // Don't overwrite index entries for already-open documents with stale // disk content; `initialized` calls `refresh` for each open doc right // after this returns, so they will populate the index from live text. @@ -456,19 +674,95 @@ impl Backend { .iter() .map(|e| e.key().as_str().to_string()) .collect(); - let Ok(mut idx) = self.index.write() else { - return; - }; - for (uri, defs, refs, tags, text) in base_scanned.into_iter().chain(scanned) { - if let Some(text) = text { - self.virtual_files.insert(uri.clone(), text); - } - if !open.contains(&uri) { - idx.set_file(&uri, defs); - idx.set_file_refs(&uri, refs); - idx.set_file_tags(&uri, tags); + { + let Ok(mut idx) = self.index.write() else { + return; + }; + for (uri, defs, refs, tags, models, text) in base_scanned.into_iter().chain(scanned) { + if let Some(text) = text { + self.virtual_files.insert(uri.clone(), text); + } + if !open.contains(&uri) { + idx.set_file(&uri, defs); + idx.set_file_refs(&uri, refs); + idx.set_file_tags(&uri, tags); + idx.set_file_models(&uri, models); + } } } + self.end_scan_progress(progress_token, ini_total, model_total) + .await; + } + + /// Ask the client to show an indexing spinner. Returns the token to end + /// it with, or `None` when the client doesn't support work-done progress. + async fn begin_scan_progress(&self) -> Option { + if !self.progress_support.get().copied().unwrap_or(false) { + return None; + } + let token = NumberOrString::String("zerosyntax/indexing".into()); + self.client + .send_request::(WorkDoneProgressCreateParams { + token: token.clone(), + }) + .await + .ok()?; + self.client + .send_notification::(ProgressParams { + token: token.clone(), + value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin( + WorkDoneProgressBegin { + title: "Indexing game data".into(), + message: Some("scanning workspace and base INI roots".into()), + cancellable: Some(false), + // Signals that reports will carry a percentage. + percentage: Some(0), + }, + )), + }) + .await; + Some(token) + } + + /// Forward one `done/total` update to the client's progress UI. + async fn report_scan_progress( + &self, + token: &Option, + done: usize, + total: usize, + ) { + let Some(token) = token else { return }; + self.client + .send_notification::(ProgressParams { + token: token.clone(), + value: ProgressParamsValue::WorkDone(WorkDoneProgress::Report( + WorkDoneProgressReport { + message: Some(format!("{done}/{total} files")), + percentage: Some((done * 100 / total.max(1)) as u32), + cancellable: Some(false), + }, + )), + }) + .await; + } + + async fn end_scan_progress( + &self, + token: Option, + ini_total: usize, + model_total: usize, + ) { + let Some(token) = token else { return }; + self.client + .send_notification::(ProgressParams { + token, + value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd { + message: Some(format!( + "{ini_total} INI files, {model_total} W3D models indexed" + )), + })), + }) + .await; } /// The cached state for an open document (rope + parse), if any. @@ -605,6 +899,14 @@ impl LanguageServer for Backend { .unwrap_or(false); let _ = self.snippet_support.set(snippet_support); + let progress_support = params + .capabilities + .window + .as_ref() + .and_then(|w| w.work_done_progress) + .unwrap_or(false); + let _ = self.progress_support.set(progress_support); + Ok(InitializeResult { server_info: Some(ServerInfo { name: "zerosyntax-lsp".into(), @@ -662,8 +964,21 @@ impl LanguageServer for Backend { for uri in open { self.refresh(&uri).await; } + let (ini, models) = { + let idx = self.index.read().ok(); + let models = idx + .as_ref() + .map(|i| i.model_names().count()) + .unwrap_or_default(); + (self.base_indexed_count.load(Ordering::Relaxed), models) + }; self.client - .log_message(MessageType::INFO, "zerosyntax language server ready") + .log_message( + MessageType::INFO, + format!( + "zerosyntax language server ready ({ini} base INI files, {models} W3D models indexed)" + ), + ) .await; } @@ -1395,11 +1710,160 @@ mod tests { assert!(Url::parse(&scanned[0].0).is_ok()); assert!(scanned[0].1.iter().any(|d| d.name == "BigArchiveObject")); assert_eq!( - scanned[0].4.as_deref(), + scanned[0].5.as_deref(), Some("Object BigArchiveObject\nEnd\n") ); } + #[test] + fn w3d_root_scan_powers_model_and_bone_completions() { + // End-to-end over the `baseIniRoots` path: a directory containing a + // loose .w3d file is scanned, indexed, and drives completions. + let mut pivots = Vec::new(); + pivots.extend_from_slice(b"Tire01"); + pivots.resize(60, 0); + let mut bytes = Vec::new(); + bytes.extend_from_slice(&0x0000_0102u32.to_le_bytes()); + bytes.extend_from_slice(&(pivots.len() as u32).to_le_bytes()); + bytes.extend_from_slice(&pivots); + + let dir = std::env::temp_dir().join(format!("zerosyntax-w3d-{}", std::process::id())); + std::fs::create_dir_all(&dir).unwrap(); + std::fs::write(dir.join("Good.w3d"), bytes).unwrap(); + + let analyzer = Analyzer::embedded(); + let scanned = scan_roots(&analyzer, std::slice::from_ref(&dir)); + let _ = std::fs::remove_dir_all(&dir); + + let mut idx = WorkspaceIndex::new(); + for (uri, defs, refs, tags, models, _) in scanned { + idx.set_file(&uri, defs); + idx.set_file_refs(&uri, refs); + idx.set_file_tags(&uri, tags); + idx.set_file_models(&uri, models); + } + assert!(idx.is_model_asset("Good"), "model name from file stem"); + + let src = "\ +Object Tank + Draw = W3DTankDraw ModuleTag_01 + DefaultConditionState + Model = + HideSubObject = + End + End +End +"; + let parse = analyzer.parse(src); + let labels_at = |offset: usize| -> Vec { + completion::complete(&analyzer, &parse, offset as u32, Some(&idx), None) + .into_iter() + .map(|c| c.label) + .collect() + }; + let model_offset = src.find("Model = ").unwrap() + "Model = ".len(); + assert!(labels_at(model_offset).contains(&"Good".to_string())); + + let src = src.replace("Model = ", "Model = Good"); + let parse = analyzer.parse(&src); + let bone_offset = src.find("HideSubObject = ").unwrap() + "HideSubObject = ".len(); + let labels: Vec = + completion::complete(&analyzer, &parse, bone_offset as u32, Some(&idx), None) + .into_iter() + .map(|c| c.label) + .collect(); + assert!(labels.contains(&"Tire".to_string()), "{labels:?}"); + } + + #[test] + fn parses_w3d_model_names_and_members() { + fn fixed(name: &str) -> [u8; N] { + let mut out = [0; N]; + let bytes = name.as_bytes(); + out[..bytes.len().min(N)].copy_from_slice(&bytes[..bytes.len().min(N)]); + out + } + fn chunk(kind: u32, payload: Vec) -> Vec { + let mut out = Vec::new(); + out.extend_from_slice(&kind.to_le_bytes()); + out.extend_from_slice(&(payload.len() as u32).to_le_bytes()); + out.extend_from_slice(&payload); + out + } + + let mut hlod = Vec::new(); + hlod.extend_from_slice(&1u32.to_le_bytes()); + hlod.extend_from_slice(&1u32.to_le_bytes()); + hlod.extend_from_slice(&fixed::<16>("Good")); + hlod.extend_from_slice(&fixed::<16>("Good")); + + let mut pivot = Vec::new(); + pivot.extend_from_slice(&fixed::<16>("Tire01")); + pivot.resize(60, 0); + + let mut sub = Vec::new(); + sub.extend_from_slice(&0u32.to_le_bytes()); + sub.extend_from_slice(&fixed::<32>("Good.Cargo01")); + + let mut bytes = Vec::new(); + bytes.extend(chunk(0x0000_0701, hlod)); + bytes.extend(chunk(0x0000_0102, pivot)); + bytes.extend(chunk(0x0000_0704, sub)); + + let models = parse_w3d_models(&bytes, "Fallback"); + let good = models.iter().find(|m| m.name == "Good").unwrap(); + assert!(good.members.iter().any(|m| m == "Tire01"), "{good:?}"); + assert!(good.members.iter().any(|m| m == "Cargo01"), "{good:?}"); + } + + #[test] + fn parses_w3d_aggregate_and_emitter_names() { + fn fixed(name: &str) -> [u8; N] { + let mut out = [0; N]; + let bytes = name.as_bytes(); + out[..bytes.len().min(N)].copy_from_slice(&bytes[..bytes.len().min(N)]); + out + } + fn chunk(kind: u32, payload: Vec) -> Vec { + let mut out = Vec::new(); + out.extend_from_slice(&kind.to_le_bytes()); + out.extend_from_slice(&(payload.len() as u32).to_le_bytes()); + out.extend_from_slice(&payload); + out + } + // Version + Name[16] header, wrapped in its container chunk. + let mut header = Vec::new(); + header.extend_from_slice(&1u32.to_le_bytes()); + header.extend_from_slice(&fixed::<16>("Aggro")); + let mut bytes = chunk(0x0000_0600, chunk(0x0000_0601, header)); + + let mut header = Vec::new(); + header.extend_from_slice(&1u32.to_le_bytes()); + header.extend_from_slice(&fixed::<16>("Smoke")); + bytes.extend(chunk(0x0000_0500, chunk(0x0000_0501, header))); + + let models = parse_w3d_models(&bytes, ""); + assert!(models.iter().any(|m| m.name == "Aggro"), "{models:?}"); + assert!(models.iter().any(|m| m.name == "Smoke"), "{models:?}"); + } + + #[test] + fn w3d_chunk_walker_survives_hostile_deep_nesting() { + // A self-nesting container at every level: each 8-byte header claims + // the rest of the file as payload. Without a depth cap this recursed + // once per 8 bytes and could overflow the stack on a large file. + let total: usize = 64 * 1024; + let mut bytes = Vec::with_capacity(total); + let mut remaining = total; + while remaining >= 8 { + bytes.extend_from_slice(&0x0000_0700u32.to_le_bytes()); + bytes.extend_from_slice(&((remaining - 8) as u32).to_le_bytes()); + remaining -= 8; + } + // Must terminate without smashing the stack; content is garbage. + let _ = parse_w3d_models(&bytes, "Fallback"); + } + #[test] #[cfg(windows)] fn canonical_uri_normalises_windows_file_uri() { diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index 6604041..9d78a2e 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs @@ -23,6 +23,23 @@ fn header_tokens(node: &SyntaxNode) -> impl Iterator + '_ { .filter_map(move |el| el.into_token().filter(|t| !token_kind(t).is_trivia())) } +fn header_value_tokens(node: &SyntaxNode) -> Vec { + let mut seen_key = false; + let mut out = Vec::new(); + for element in node.children_with_tokens() { + let Some(token) = element.into_token() else { + break; + }; + match token_kind(&token) { + SyntaxKind::NEWLINE => break, + SyntaxKind::WORD if !seen_key => seen_key = true, + SyntaxKind::WORD | SyntaxKind::STRING if seen_key => out.push(token), + _ => {} + } + } + out +} + /// A top-level block, e.g. `Weapon AK47 ... End`. #[derive(Debug, Clone)] pub struct Block(pub SyntaxNode); @@ -80,6 +97,11 @@ impl Module { self.word_after_equals(1) } + /// Header arguments after the slot keyword, with or without `=`. + pub fn argument_tokens(&self) -> Vec { + header_value_tokens(&self.0) + } + fn word_after_equals(&self, nth: usize) -> Option { let mut seen_equals = false; let mut skip = nth; @@ -132,16 +154,7 @@ impl Field { /// another separator (INI.cpp seps are `" \n\r\t="`), so `RemoveModule /// ModuleTag_01` carries a value exactly like `Key = Value` does. pub fn value_tokens(&self) -> Vec { - let mut seen_key = false; - let mut out = Vec::new(); - for t in header_tokens(&self.0) { - match token_kind(&t) { - SyntaxKind::WORD if !seen_key => seen_key = true, - SyntaxKind::WORD | SyntaxKind::STRING if seen_key => out.push(t), - _ => {} - } - } - out + header_value_tokens(&self.0) } } diff --git a/crates/syntax/src/lexer.rs b/crates/syntax/src/lexer.rs index 5cf17aa..088f3d5 100644 --- a/crates/syntax/src/lexer.rs +++ b/crates/syntax/src/lexer.rs @@ -20,7 +20,7 @@ enum RawToken { Newline, // `;` to end of line. - #[regex(r";[^\n\r]*")] + #[regex(r";[^\n\r]*", allow_greedy = true)] Comment, #[token("=")] diff --git a/docs/release.md b/docs/release.md index 4e84dc2..cbf9a36 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,16 +1,33 @@ # Release process -Releases are tag-driven. The tag version must match the Rust workspace version -in `Cargo.toml`. +`dev` is the staging and default branch. `prod` contains live releases. Both +release types are started manually from the `Release` workflow on the `dev` +branch; tags created by the workflow do not trigger another workflow. -## Prerequisites +## Versioning -- Push access to `main`. -- A clean checkout of `main`. -- Optional: repository secret `VSCE_PAT` to publish VS Code Marketplace builds. - Without it, the workflow still creates the GitHub Release and `.vsix` assets. +`[workspace.package].version` in `Cargo.toml` is the release version and must be +a plain `major.minor.patch` value. The workflow stamps the VS Code extension +with that version while packaging, so its committed manifest is not a release +input. -## Before tagging +- A pre-release from version `1.0.5` gets a unique tag such as + `v1.0.5-pre.42` on the tested `dev` commit. +- A live release gets `v1.0.5` on the `dev`-to-`prod` merge commit. + +Tags are immutable. Do not reuse or move a release tag; bump the Cargo version +instead. GitHub pre-releases do not publish to the VS Code Marketplace. This +keeps the later live extension on the same Cargo version without conflicting +with Marketplace's numeric version rules. + +The historical `v1.0.4` GitHub pre-release used the stable tag shape and also +published Marketplace version `1.0.4`. It remains as-is; `1.0.5` is the next +available live version. + +## Before dispatching + +Commit the version bump to `dev`, then run the normal local checks when +appropriate: ```sh cargo test --locked @@ -23,46 +40,43 @@ npm run compile cd ../.. ``` -Run the corpus gate when the ignored corpus is available: - -```sh -scripts/fetch-corpus.sh -cargo test --release -p zerosyntax-analysis --test corpus -- --ignored --nocapture -``` - -On Windows, use `pwsh scripts/fetch-corpus.ps1`. +The release workflow repeats CI and the real-corpus gate before building any +release assets. -## Version bump +## Running a pre-release -1. Update `[workspace.package].version` in `Cargo.toml`. -2. Update `editors/vscode/package.json` if preparing a local package. The - release workflow stamps the extension version from the tag during packaging. -3. Run `cargo check --locked` if `Cargo.lock` changes are expected. -4. Commit the version bump. +1. Open **Actions → Release → Run workflow**. +2. Select the `dev` branch and `prerelease`. +3. Run the workflow. -## Tag and publish +The workflow pins the selected `dev` commit, runs all gates, builds Windows x64 +and Linux x64 server archives and platform VSIX packages, then creates a GitHub +pre-release with checksums. It does not change `prod` or publish to Marketplace. -```sh -git tag vX.Y.Z -git push origin main -git push origin vX.Y.Z -``` +## Running a live release -The `Release` workflow will: +1. Open **Actions → Release → Run workflow**. +2. Select the `dev` branch and `release`. +3. Run the workflow. -- Re-run CI. -- Verify the tag matches the Rust workspace version. -- Build `zerosyntax-lsp` for Windows x64 and Linux x64. -- Package platform-specific VS Code `.vsix` files. -- Create a GitHub Release with checksums. -- Publish to the VS Code Marketplace only when `VSCE_PAT` is configured. +After all gates and packages succeed, the workflow creates a `dev` → `prod` +PR and merges it automatically. The merge is rejected if `dev` moved since the +workflow started. The merge commit receives the stable tag and GitHub Release; +the packaged extensions are then published to Marketplace when `VSCE_PAT` is +configured. -## GitHub repository settings +If `prod` contains changes that are not in `dev`, the workflow stops before +building and asks for `prod` to be merged back into `dev` first. -Protect `main` with: +## Repository settings -- Require pull requests before merging. -- Require one maintainer approval. -- Require status checks from CI. -- Require branches to be up to date before merging. -- Block force pushes and direct pushes. +- Keep `dev` as the default branch so the manual workflow is available. +- Keep normal pull-request and CI protection on `dev`. +- Under **Settings → Actions → General**, enable **Allow GitHub Actions to + create and approve pull requests**. The workflow already requests only the + required `contents: write` and `pull-requests: write` token scopes. +- Keep `prod` available for the workflow-created merge PR. If branch protection + is later added to `prod`, give the release workflow a deliberate bypass or + change the flow to wait for approval. +- Configure `VSCE_PAT` to publish live VS Code Marketplace builds. Without it, + the stable GitHub Release still succeeds. diff --git a/editors/vscode/package-lock.json b/editors/vscode/package-lock.json index 7321286..1040835 100644 --- a/editors/vscode/package-lock.json +++ b/editors/vscode/package-lock.json @@ -1,12 +1,12 @@ { "name": "zerosyntax-vscode", - "version": "1.0.2", + "version": "1.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "zerosyntax-vscode", - "version": "1.0.2", + "version": "1.0.4", "license": "MIT", "dependencies": { "vscode-languageclient": "^9.0.1" @@ -17,8 +17,8 @@ "@types/vscode": "^1.84.0", "@vscode/test-electron": "^3.0.0", "@vscode/vsce": "^3.9.2", - "mocha": "^11.7.6", - "typescript": "^5.4.0" + "mocha": "^11.3.0", + "typescript": "^6.0.3" }, "engines": { "vscode": "^1.84.0" @@ -173,22 +173,22 @@ } }, "node_modules/@azure/msal-browser": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-5.16.0.tgz", - "integrity": "sha512-Wc75FGnQgYpsm5jsOqn1H8AXsh8vXruA6vwip1nhjrJxwby7juxKAIVLr7csepmHiwdZGr6EwI5BlSc3PizEtQ==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-5.17.0.tgz", + "integrity": "sha512-/yTnW2TCk9Mh+2b/NOaHAN+MryUNxzRTaJD/YtrqOA9bpBWfTXn/iyReRbaLrK/btBo3stEzLyEvuWp2NZ5DuA==", "dev": true, "license": "MIT", "dependencies": { - "@azure/msal-common": "16.11.0" + "@azure/msal-common": "16.11.1" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.11.0.tgz", - "integrity": "sha512-UikJOtMwkFpZNzTH6Dqk8UTUPbow15zH3e0UjGYZy69lYENW/S05gMLhbxI2eonz66uALhIljvhsSMEb6+O30g==", + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-16.11.1.tgz", + "integrity": "sha512-yPohvMwWLv1XnaWnIUyKUh8CvcVChCGqG/VluGwfGmaAfrZTNt5yQ+sIs462Sgw6+e2K83KGmMJ860p73ZSCrw==", "dev": true, "license": "MIT", "engines": { @@ -196,13 +196,13 @@ } }, "node_modules/@azure/msal-node": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.3.1.tgz", - "integrity": "sha512-sqqv3L1UOI4KDXonNtbxPYUgbSWVXqxvmmb6BUw9n4P/UXgG+cVur3dLWQN4Cz7qQ+UJROCCxMXlksm7gIq0Sw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-5.4.0.tgz", + "integrity": "sha512-6EZEParwHRlnSSIikw8FNAnAzwmh71uhveUXdPNFeZFviJ9SH+rwFiurhjzXqICYTrpm3E+dj693QOwfPbJXAQ==", "dev": true, "license": "MIT", "dependencies": { - "@azure/msal-common": "16.11.0", + "@azure/msal-common": "16.11.1", "jsonwebtoken": "^9.0.0" }, "engines": { @@ -636,9 +636,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz", - "integrity": "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==", + "version": "20.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", + "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", "dev": true, "license": "MIT", "dependencies": { @@ -660,9 +660,9 @@ "license": "MIT" }, "node_modules/@types/vscode": { - "version": "1.120.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.120.0.tgz", - "integrity": "sha512-feaT4Rst+FkTch5zz/ZbNCxoIvo55YU80Be2kiL7OJcod4+CUYf2lUBPdIJzozNnSEMq1VRTGrWEcCGFB3fBmA==", + "version": "1.125.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.125.0.tgz", + "integrity": "sha512-0icm/ZQAaism87P0ekHqi4/Ju9du+Tm0RUW+y7vqRsxY2cY0FNRX1nAnaW7nT6npPt2tfHiheZ55Zm9UhqonFA==", "dev": true, "license": "MIT" }, @@ -890,45 +890,6 @@ "win32" ] }, - "node_modules/@vscode/vsce/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@vscode/vsce/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@vscode/vsce/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -1037,10 +998,14 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/base64-js": { "version": "1.5.1", @@ -1124,12 +1089,16 @@ "license": "BSD-2-Clause" }, "node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -2153,45 +2122,6 @@ "node": ">= 6" } }, - "node_modules/glob/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globby": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", @@ -3061,15 +2991,19 @@ } }, "node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "license": "ISC", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -3138,6 +3072,23 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/mocha/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/mocha/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -3674,9 +3625,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", - "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -4109,9 +4060,9 @@ } }, "node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4773,9 +4724,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4901,6 +4852,33 @@ "vscode": "^1.82.0" } }, + "node_modules/vscode-languageclient/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/vscode-languageclient/node_modules/brace-expansion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/vscode-languageclient/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/vscode-languageserver-protocol": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", diff --git a/editors/vscode/package.json b/editors/vscode/package.json index df5f592..5acd556 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -2,7 +2,7 @@ "name": "zerosyntax-vscode", "displayName": "ZeroSyntax v2", "description": "Language support (diagnostics, completion, semantic highlighting) for C&C Generals: Zero Hour INI files, powered by ZeroSyntax v2.", - "version": "1.0.2", + "version": "1.0.4", "license": "MIT", "repository": { "type": "GitHub", @@ -61,7 +61,7 @@ "items": { "type": "string" }, - "markdownDescription": "Directories or `.big` archives containing base game/mod INI files that should be treated as already loaded before `map.ini`/`solo.ini`. Changing this restarts the language server." + "markdownDescription": "Directories or `.big` archives containing base game/mod INI files and W3D assets. INI definitions are treated as already loaded before `map.ini`/`solo.ini`; W3D assets power model and bone completions/diagnostics. Changing this restarts the language server." }, "zerosyntax.trace.server": { "type": "string", @@ -93,7 +93,7 @@ "@types/vscode": "^1.84.0", "@vscode/test-electron": "^3.0.0", "@vscode/vsce": "^3.9.2", - "mocha": "^11.7.6", - "typescript": "^5.4.0" + "mocha": "^11.3.0", + "typescript": "^6.0.3" } -} \ No newline at end of file +} diff --git a/editors/vscode/tsconfig.json b/editors/vscode/tsconfig.json index 54550c4..2f38aca 100644 --- a/editors/vscode/tsconfig.json +++ b/editors/vscode/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { - "module": "commonjs", + "module": "node16", + "moduleResolution": "node16", "target": "ES2020", "lib": ["ES2020"], "outDir": "out", @@ -8,6 +9,7 @@ "sourceMap": true, "strict": true, "esModuleInterop": true, + "types": ["node", "vscode"], "skipLibCheck": true }, "include": ["src"],