Compare commits
No commits in common. "base" and "speed_up_module_loading" have entirely different histories.
base
...
speed_up_m
5632 changed files with 167076 additions and 200907 deletions
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
# We base things of WebKit + Allman braces
|
||||
# Compatible with clang-format-22 (enforced by tools/run_clang_format.py)
|
||||
# Compatible with clang-format-20
|
||||
Language: Cpp
|
||||
|
||||
# Access modifiers
|
||||
|
|
@ -28,7 +28,8 @@ AllowShortFunctionsOnASingleLine: None
|
|||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: None
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
LambdaBodyIndentation: Signature
|
||||
|
||||
# Note: LambdaBodyIndentation not available in clang-format-20
|
||||
|
||||
# Template declarations
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
|
@ -70,8 +71,6 @@ BinPackParameters: false
|
|||
# Namespaces
|
||||
CompactNamespaces: false
|
||||
NamespaceIndentation: None
|
||||
WrapNamespaceBodyWithEmptyLines: Always
|
||||
SeparateDefinitionBlocks: Always
|
||||
|
||||
# Braced lists and initializers
|
||||
Cpp11BracedListStyle: false
|
||||
|
|
@ -90,7 +89,8 @@ MaxEmptyLinesToKeep: 1
|
|||
# Pointer and reference alignment
|
||||
PointerAlignment: Left
|
||||
ReferenceAlignment: Pointer
|
||||
QualifierAlignment: Left # West Const
|
||||
|
||||
# Note: QualifierAlignment not available in clang-format-20, use manual const placement
|
||||
|
||||
# Comments
|
||||
ReflowComments: Always
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@
|
|||
"remoteUser": "xiadmin",
|
||||
"remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" },
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
|
||||
"moby": false
|
||||
}
|
||||
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
|
|
|
|||
|
|
@ -80,18 +80,6 @@ indent_brace_style = allman # This is unfortunately ignored in Visual Studio
|
|||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[*.{yml,yaml}]
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
|
|
|||
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -12,8 +12,6 @@
|
|||
*.h text eol=lf
|
||||
*.sql text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.yaml text eol=lf
|
||||
*.yml text eol=lf
|
||||
|
||||
# Retaining CRLF line ends in the documentation dir (for now..)
|
||||
*.txt text eol=crlf
|
||||
|
|
|
|||
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
|
|
@ -15,9 +15,9 @@ jobs:
|
|||
name: Clang Tidy
|
||||
uses: ./.github/workflows/runner_build.yml
|
||||
with:
|
||||
runner: ubuntu-26.04
|
||||
runner: ubuntu-24.04
|
||||
compiler: clang
|
||||
compiler_version: 22
|
||||
compiler_version: 20
|
||||
build_type: Debug
|
||||
tracy: false
|
||||
build_modules: false
|
||||
|
|
@ -64,9 +64,9 @@ jobs:
|
|||
upload_artifact: false
|
||||
clang_tidy: false
|
||||
- build_type: Debug
|
||||
runner: ubuntu-26.04
|
||||
runner: ubuntu-24.04
|
||||
compiler: gcc
|
||||
compiler_version: 15
|
||||
compiler_version: 14
|
||||
tracy: false
|
||||
build_modules: false
|
||||
save_cache: true
|
||||
|
|
@ -93,8 +93,8 @@ jobs:
|
|||
- build_type: Release
|
||||
os: ubuntu
|
||||
compiler: gcc
|
||||
compiler_version: 15
|
||||
clang_format_version: 22
|
||||
compiler_version: 14
|
||||
clang_format_version: 20
|
||||
tracy: false
|
||||
build_modules: false
|
||||
save_cache: false
|
||||
|
|
@ -110,8 +110,8 @@ jobs:
|
|||
- build_type: Release
|
||||
os: alpine
|
||||
compiler: clang
|
||||
compiler_version: 22
|
||||
clang_format_version: 22
|
||||
compiler_version: 20
|
||||
clang_format_version: 20
|
||||
tracy: false
|
||||
build_modules: false
|
||||
save_cache: false
|
||||
|
|
|
|||
9
.github/workflows/changelog.yml
vendored
9
.github/workflows/changelog.yml
vendored
|
|
@ -9,15 +9,14 @@ on:
|
|||
jobs:
|
||||
Publish_Changelog:
|
||||
name: Generate and Publish Changelog
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- run: git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
- run: git config --global user.name "github-actions[bot]"
|
||||
- uses: actions/checkout@v1
|
||||
- uses: fregante/setup-git-user@v1
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python3
|
||||
sudo apt-get install -y python3.7
|
||||
pip3 install requests
|
||||
- name: Generate changelog
|
||||
run: |
|
||||
|
|
|
|||
2
.github/workflows/check_template.yml
vendored
2
.github/workflows/check_template.yml
vendored
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
permissions: write-all
|
||||
steps:
|
||||
- name: Comment on unchecked boxes in template
|
||||
uses: actions/github-script@v9
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
function count_instances(string, word)
|
||||
|
|
|
|||
12
.github/workflows/codeql_analysis.yml
vendored
12
.github/workflows/codeql_analysis.yml
vendored
|
|
@ -36,16 +36,16 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y software-properties-common cmake libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev binutils-dev libzstd-dev libdwarf-dev
|
||||
sudo apt-get install -y software-properties-common cmake libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev binutils-dev
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
trap-caching: false
|
||||
languages: ${{ matrix.language }}
|
||||
|
|
@ -57,7 +57,7 @@ jobs:
|
|||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
# - name: Autobuild
|
||||
# uses: github/codeql-action/autobuild@v4
|
||||
# uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
|
@ -73,7 +73,7 @@ jobs:
|
|||
cmake --build build -j4
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
# https://josh-ops.com/posts/github-codeql-ignore-files/
|
||||
upload: false # disable the upload here - we will upload in a different action
|
||||
|
|
@ -89,6 +89,6 @@ jobs:
|
|||
output: sarif-results/${{ matrix.language }}.sarif
|
||||
|
||||
- name: Upload SARIF
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: sarif-results/${{ matrix.language }}.sarif
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Comment on keywords in Discussion
|
||||
uses: actions/github-script@v9
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
// Define the keywords to check (all lower-case for case-insensitive matching)
|
||||
|
|
|
|||
20
.github/workflows/docker_build.yml
vendored
20
.github/workflows/docker_build.yml
vendored
|
|
@ -67,13 +67,13 @@ jobs:
|
|||
echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
|
||||
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
|
||||
|
||||
- uses: docker/login-action@v4
|
||||
- uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
|
@ -88,12 +88,12 @@ jobs:
|
|||
f.write("renamer\n")
|
||||
EOF
|
||||
|
||||
- uses: docker/setup-buildx-action@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
id: setup_buildx
|
||||
|
||||
- name: Restore build cache
|
||||
if: ${{ !inputs.save_cache }}
|
||||
uses: actions/cache/restore@v5
|
||||
uses: actions/cache/restore@v4
|
||||
env:
|
||||
cmake_hash: ${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
|
||||
source_hash: ${{ hashFiles('src/**/*', 'ext/**/*') }}
|
||||
|
|
@ -108,7 +108,7 @@ jobs:
|
|||
- name: Cache build
|
||||
id: cache_build
|
||||
if: ${{ inputs.save_cache }}
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cmake_hash: ${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
|
||||
source_hash: ${{ hashFiles('src/**/*', 'ext/**/*') }}
|
||||
|
|
@ -121,7 +121,7 @@ jobs:
|
|||
${{ format('buildcache-docker-{0}-{1}{2}-{3}-{4}-', inputs.os, inputs.compiler, inputs.compiler_version, inputs.build_type, env.cmake_hash) }}
|
||||
|
||||
- name: Inject cache into container
|
||||
uses: reproducible-containers/buildkit-cache-dance@v3.4.0
|
||||
uses: reproducible-containers/buildkit-cache-dance@v3.2.0
|
||||
with:
|
||||
builder: ${{ steps.setup_buildx.outputs.name }}
|
||||
cache-map: |
|
||||
|
|
@ -145,7 +145,7 @@ jobs:
|
|||
|
||||
- name: Docker meta
|
||||
id: docker-meta
|
||||
uses: docker/metadata-action@v6
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ env.REPO }}
|
||||
tags: |
|
||||
|
|
@ -161,7 +161,7 @@ jobs:
|
|||
|
||||
- name: Build devtools image
|
||||
if: ${{ inputs.publish && vars.PUBLISH_DOCKER != '' }}
|
||||
uses: docker/build-push-action@v7
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ format('./docker/{0}.Dockerfile', inputs.os) }}
|
||||
|
|
@ -173,7 +173,7 @@ jobs:
|
|||
tags: ${{ format('ghcr.io/{0}/devtools:{1}', env.REPO_OWNER, inputs.os) }}
|
||||
|
||||
- name: Docker build and push
|
||||
uses: docker/build-push-action@v7
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ format('./docker/{0}.Dockerfile', inputs.os) }}
|
||||
|
|
@ -194,7 +194,7 @@ jobs:
|
|||
|
||||
- name: Archive image
|
||||
if: ${{ inputs.upload_artifact || (inputs.publish && vars.PUBLISH_DOCKER == '') }}
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ format('LSB_{0}_image_{1}', inputs.os, github.sha) }}
|
||||
path: ${{ format('{0}/LSB_{1}_image_{2}.tar', runner.temp, inputs.os, github.sha) }}
|
||||
|
|
|
|||
8
.github/workflows/docker_test.yml
vendored
8
.github/workflows/docker_test.yml
vendored
|
|
@ -57,21 +57,21 @@ jobs:
|
|||
echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
|
||||
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: recursive # For navmeshes
|
||||
|
||||
- name: Download artifact
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ env.artifact_name }}
|
||||
path: ${{ runner.temp }}
|
||||
|
||||
- name: Download previous artifact
|
||||
if: ${{ (github.event_name == 'workflow_run' || github.event_name == 'workflow_dispatch') && vars.PUBLISH_DOCKER == ''}}
|
||||
uses: dawidd6/action-download-artifact@v21
|
||||
uses: dawidd6/action-download-artifact@v3
|
||||
with:
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: ${{ env.artifact_name }}
|
||||
|
|
@ -119,7 +119,7 @@ jobs:
|
|||
- name: Run xi_test
|
||||
id: xi_test
|
||||
continue-on-error: true
|
||||
run: docker exec test-server /bin/bash -c './xi_test --keep-going --retry 5 --output log/tests.ctrf.json'
|
||||
run: docker exec test-server /bin/bash -c './xi_test --keep-going --output log/tests.ctrf.json'
|
||||
|
||||
- name: Publish Test Report
|
||||
if: ${{ !cancelled() }}
|
||||
|
|
|
|||
147
.github/workflows/pr_checks.yml
vendored
147
.github/workflows/pr_checks.yml
vendored
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
# $GITHUB_WORKSPACE is the workspace in the container (/__w/server/server)
|
||||
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ jobs:
|
|||
run: tr -d '\r' < sanity_checks_summary.md >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Upload changed files as artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: changed-files
|
||||
path: changed-files.txt
|
||||
|
|
@ -63,7 +63,7 @@ jobs:
|
|||
shell: bash
|
||||
steps:
|
||||
- name: Download Changed Files
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: changed-files
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ jobs:
|
|||
|
||||
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
if: ${{ steps.check-changes.outputs.lua_changes == 'true' }}
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
|
@ -93,10 +93,6 @@ jobs:
|
|||
python -m pip install --upgrade pip setuptools wheel
|
||||
python -m pip install --upgrade -r ./tools/requirements.txt
|
||||
|
||||
- name: Generate codegen Lua enums
|
||||
if: ${{ steps.check-changes.outputs.lua_changes == 'true' }}
|
||||
run: python -m tools.codegen "$RUNNER_TEMP/codegen-out"
|
||||
|
||||
- name: Run Lua Language Server
|
||||
id: run_lls
|
||||
if: ${{ steps.check-changes.outputs.lua_changes == 'true' }}
|
||||
|
|
@ -133,137 +129,14 @@ jobs:
|
|||
echo "Lua Language Server failed. See summary for details."
|
||||
exit 1
|
||||
|
||||
Schema_Validation:
|
||||
needs: Sanity_Checks
|
||||
name: Data validation
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Download Changed Files
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: changed-files
|
||||
|
||||
- name: Check for data/ or codegen changes
|
||||
id: changed
|
||||
run: |
|
||||
mapfile -t changed_files < changed-files.txt
|
||||
touched=false
|
||||
for f in "${changed_files[@]}"; do
|
||||
if [[ $f == data/* || $f == tools/codegen/* ]]; then
|
||||
touched=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "touched=$touched" >> "$GITHUB_OUTPUT"
|
||||
echo "Touched: $touched"
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
if: steps.changed.outputs.touched == 'true'
|
||||
|
||||
- name: Setup Python
|
||||
if: steps.changed.outputs.touched == 'true'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.14"
|
||||
|
||||
- name: Install Python dependencies
|
||||
if: steps.changed.outputs.touched == 'true'
|
||||
run: python -m pip install jinja2 jsonschema pyyaml
|
||||
|
||||
- name: Run codegen --validate
|
||||
if: steps.changed.outputs.touched == 'true'
|
||||
run: |
|
||||
mkdir -p "$RUNNER_TEMP/codegen-out"
|
||||
python -m tools.codegen "$RUNNER_TEMP/codegen-out" --validate
|
||||
|
||||
Formatting:
|
||||
needs: Sanity_Checks
|
||||
name: Data formatting
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Download Changed Files
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: changed-files
|
||||
|
||||
- name: Filter data/ changed files
|
||||
id: changed
|
||||
run: |
|
||||
mapfile -t changed_files < changed-files.txt
|
||||
yaml_files=()
|
||||
other_files=()
|
||||
for f in "${changed_files[@]}"; do
|
||||
if [[ $f == data/*.yaml || $f == data/*.yml ]]; then
|
||||
yaml_files+=("$f")
|
||||
elif [[ $f == data/* ]]; then
|
||||
other_files+=("$f")
|
||||
fi
|
||||
done
|
||||
echo "yaml=${yaml_files[*]}" >> "$GITHUB_OUTPUT"
|
||||
echo "other=${other_files[*]}" >> "$GITHUB_OUTPUT"
|
||||
echo "Changed YAML: ${yaml_files[*]}"
|
||||
echo "Changed other: ${other_files[*]}"
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
if: steps.changed.outputs.yaml != '' || steps.changed.outputs.other != ''
|
||||
|
||||
- name: Setup Python
|
||||
if: steps.changed.outputs.yaml != ''
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.14"
|
||||
|
||||
- name: Install Python dependencies
|
||||
if: steps.changed.outputs.yaml != ''
|
||||
run: python -m pip install pyyaml ruamel.yaml
|
||||
|
||||
- name: Check YAML formatting
|
||||
if: steps.changed.outputs.yaml != ''
|
||||
run: python tools/yaml/format.py ${{ steps.changed.outputs.yaml }} --check
|
||||
|
||||
- name: Cache prettier results
|
||||
if: steps.changed.outputs.other != ''
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /tmp/prettier-cache
|
||||
key: prettier-cache-${{ hashFiles('data/**/*.json') }}
|
||||
restore-keys: prettier-cache-
|
||||
|
||||
- name: Run prettier
|
||||
if: steps.changed.outputs.other != ''
|
||||
run: |
|
||||
set +e
|
||||
FAILED=$(npx --yes prettier@3 --cache --cache-strategy content --cache-location /tmp/prettier-cache --list-different ${{ steps.changed.outputs.other }})
|
||||
set -e
|
||||
if [ -z "$FAILED" ]; then
|
||||
echo "All files use Prettier code style!"
|
||||
exit 0
|
||||
fi
|
||||
echo "::group::Files needing reformat"
|
||||
echo "$FAILED"
|
||||
echo "::endgroup::"
|
||||
echo "::group::Diff"
|
||||
for f in $FAILED; do
|
||||
diff -u "$f" <(npx --yes prettier@3 "$f") || true
|
||||
done
|
||||
echo "::endgroup::"
|
||||
echo "Run \`npx prettier --write data\` locally to fix."
|
||||
exit 1
|
||||
|
||||
Clang_Tidy:
|
||||
needs: Sanity_Checks
|
||||
name: Clang Tidy
|
||||
uses: ./.github/workflows/runner_build.yml
|
||||
with:
|
||||
runner: ubuntu-26.04
|
||||
runner: ubuntu-24.04
|
||||
compiler: clang
|
||||
compiler_version: 22
|
||||
compiler_version: 20
|
||||
build_type: Debug
|
||||
build_modules: false
|
||||
tracy: false
|
||||
|
|
@ -287,9 +160,9 @@ jobs:
|
|||
compiler: appleClang
|
||||
build_modules: false
|
||||
- build_type: Debug
|
||||
runner: ubuntu-26.04
|
||||
runner: ubuntu-24.04
|
||||
compiler: gcc
|
||||
compiler_version: 15
|
||||
compiler_version: 14
|
||||
build_modules: false
|
||||
uses: ./.github/workflows/runner_build.yml
|
||||
with:
|
||||
|
|
@ -316,9 +189,9 @@ jobs:
|
|||
- runner: macos-26
|
||||
test_modules: false
|
||||
multi_process: false
|
||||
xi_test: true
|
||||
xi_test: false
|
||||
startup_checks: true
|
||||
- runner: ubuntu-26.04
|
||||
- runner: ubuntu-24.04
|
||||
test_modules: false
|
||||
multi_process: false
|
||||
xi_test: true
|
||||
|
|
|
|||
2
.github/workflows/pr_labels.yml
vendored
2
.github/workflows/pr_labels.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
permissions: write-all
|
||||
steps:
|
||||
- name: Check for blocking labels
|
||||
uses: actions/github-script@v9
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const response = await github.rest.issues.listLabelsOnIssue({
|
||||
|
|
|
|||
10
.github/workflows/publish_meshes.yml
vendored
10
.github/workflows/publish_meshes.yml
vendored
|
|
@ -23,23 +23,23 @@ jobs:
|
|||
echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v4
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ env.REPO_OWNER }}/ximeshes
|
||||
tags: |
|
||||
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
org.opencontainers.image.description=Line-of-sight and navigation meshes for use with LandSandBoat server.
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v7
|
||||
uses: docker/build-push-action@v6
|
||||
env:
|
||||
BUILDX_NO_DEFAULT_ATTESTATIONS: 1
|
||||
with:
|
||||
|
|
|
|||
41
.github/workflows/runner_build.yml
vendored
41
.github/workflows/runner_build.yml
vendored
|
|
@ -64,7 +64,7 @@ jobs:
|
|||
steps:
|
||||
- name: Download changed files artifact
|
||||
if: ${{ inputs.optional_build }}
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: changed-files
|
||||
|
||||
|
|
@ -92,14 +92,14 @@ jobs:
|
|||
|
||||
- name: Checkout
|
||||
if: ${{ env.SKIP_BUILD != 'true' }}
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Install dependencies (macOS)
|
||||
if: ${{ runner.os == 'macOS' && env.SKIP_BUILD != 'true' }}
|
||||
run: |
|
||||
brew install --quiet \
|
||||
brew update && brew install --quiet \
|
||||
mariadb \
|
||||
zeromq \
|
||||
luajit \
|
||||
|
|
@ -108,7 +108,7 @@ jobs:
|
|||
- name: Setup LLVM Clang (macOS)
|
||||
if: ${{ runner.os == 'macOS' && startsWith(inputs.compiler, 'clang') && env.SKIP_BUILD != 'true' }}
|
||||
run: |
|
||||
brew install --quiet \
|
||||
brew update && brew install --quiet \
|
||||
llvm@${{ inputs.compiler_version }} \
|
||||
lld@${{ inputs.compiler_version }}
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ jobs:
|
|||
- name: Setup GCC (macOS)
|
||||
if: ${{ runner.os == 'macOS' && startsWith(inputs.compiler, 'gcc') && env.SKIP_BUILD != 'true' }}
|
||||
run: |
|
||||
brew install --quiet gcc@${{ inputs.compiler_version }}
|
||||
brew update && brew install --quiet gcc@${{ inputs.compiler_version }}
|
||||
GCC_PREFIX=$(brew --prefix gcc@${{ inputs.compiler_version }})
|
||||
echo "PATH=$GCC_PREFIX/bin:$PATH" >> $GITHUB_ENV
|
||||
echo "CC=$GCC_PREFIX/bin/gcc-${{ inputs.compiler_version }}" >> $GITHUB_ENV
|
||||
|
|
@ -139,7 +139,6 @@ jobs:
|
|||
run: |
|
||||
sudo apt-get update && sudo apt-get install --assume-yes --no-install-recommends --quiet \
|
||||
binutils-dev \
|
||||
libdwarf-dev \
|
||||
libluajit-5.1-dev \
|
||||
libmariadb-dev-compat \
|
||||
libssl-dev \
|
||||
|
|
@ -147,8 +146,7 @@ jobs:
|
|||
luajit \
|
||||
mariadb-client \
|
||||
tzdata \
|
||||
zlib1g-dev \
|
||||
libzstd-dev
|
||||
zlib1g-dev
|
||||
|
||||
- name: Setup GCC (Linux)
|
||||
if: ${{ runner.os == 'Linux' && startsWith(inputs.compiler, 'gcc') && env.SKIP_BUILD != 'true' }}
|
||||
|
|
@ -175,25 +173,21 @@ jobs:
|
|||
|
||||
- name: Setup MSVC
|
||||
if: ${{ runner.os == 'Windows' && env.SKIP_BUILD != 'true' }}
|
||||
uses: TheMrMilchmann/setup-msvc-dev@v4
|
||||
uses: TheMrMilchmann/setup-msvc-dev@v3
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: Setup sccache
|
||||
if: ${{ env.SKIP_BUILD != 'true' }}
|
||||
uses: mozilla-actions/sccache-action@v0.0.10
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
with:
|
||||
disable_annotations: ${{ !inputs.save_cache }}
|
||||
|
||||
- name: Setup Python
|
||||
if: ${{ env.SKIP_BUILD != 'true' }}
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.14'
|
||||
|
||||
- name: Install Python codegen deps
|
||||
if: ${{ env.SKIP_BUILD != 'true' }}
|
||||
run: python -m pip install jinja2 jsonschema pyyaml
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Enable modules
|
||||
if: ${{ inputs.build_modules && env.SKIP_BUILD != 'true' }}
|
||||
|
|
@ -209,7 +203,7 @@ jobs:
|
|||
- name: Restore build cache
|
||||
if: ${{ env.SKIP_BUILD != 'true' }}
|
||||
id: restore_build
|
||||
uses: actions/cache/restore@v5
|
||||
uses: actions/cache/restore@v4
|
||||
env:
|
||||
cmake_hash: ${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
|
||||
source_hash: ${{ hashFiles('src/**/*', 'ext/**/*') }}
|
||||
|
|
@ -236,25 +230,16 @@ jobs:
|
|||
|
||||
- name: Upload artifact
|
||||
if: ${{ inputs.upload_artifact && env.SKIP_BUILD != 'true' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ format('LSB_{0}_{1}_{2}', runner.os, inputs.build_type, github.sha) }}
|
||||
path: |
|
||||
xi_*
|
||||
tracy.tar.gz
|
||||
|
||||
- name: Remove exes from build cache
|
||||
if: ${{ inputs.save_cache && env.SKIP_BUILD != 'true' && steps.restore_build.outputs.cache-hit != 'true' }}
|
||||
run: |
|
||||
rm -f build/src/login/xi_connect*
|
||||
rm -f build/src/map/xi_map*
|
||||
rm -f build/src/search/xi_search*
|
||||
rm -f build/src/test/xi_test*
|
||||
rm -f build/src/world/xi_world*
|
||||
|
||||
- name: Cache build
|
||||
if: ${{ inputs.save_cache && env.SKIP_BUILD != 'true' && steps.restore_build.outputs.cache-hit != 'true' }}
|
||||
uses: actions/cache/save@v5
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: build
|
||||
key: ${{ steps.restore_build.outputs.cache-primary-key }}
|
||||
|
|
|
|||
18
.github/workflows/runner_test.yml
vendored
18
.github/workflows/runner_test.yml
vendored
|
|
@ -53,7 +53,7 @@ jobs:
|
|||
XI_NETWORK_SQL_LOGIN: xiadmin
|
||||
XI_NETWORK_SQL_PASSWORD: 'password'
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: recursive # For navmeshes
|
||||
|
|
@ -80,7 +80,6 @@ jobs:
|
|||
sudo apt-get update && sudo apt-get install --assume-yes --no-install-recommends --quiet \
|
||||
binutils \
|
||||
git \
|
||||
libdwarf1 \
|
||||
libmariadb-dev-compat \
|
||||
libzmq5 \
|
||||
lua5.1 \
|
||||
|
|
@ -110,10 +109,10 @@ jobs:
|
|||
${{ env.MYSQL_CMD }} -e "GRANT ALL PRIVILEGES ON ${{ env.XI_NETWORK_SQL_DATABASE }}.* TO '${{ env.XI_NETWORK_SQL_LOGIN }}'@'%';"
|
||||
${{ env.MYSQL_CMD }} -e "FLUSH PRIVILEGES;"
|
||||
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/setup-python@v5
|
||||
id: setup_python
|
||||
with:
|
||||
python-version: '3.14'
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
|
|
@ -127,19 +126,16 @@ jobs:
|
|||
echo "${{ runner.os == 'Windows' && '.venv/Scripts' || '.venv/bin' }}" >> $GITHUB_PATH
|
||||
echo "VIRTUAL_ENV=$(pwd)/.venv" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate codegen Lua enums
|
||||
run: python -m tools.codegen "$RUNNER_TEMP/codegen-out"
|
||||
|
||||
- name: Download artifact
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/download-artifact@v8
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ format('LSB_{0}_{1}_{2}', runner.os, inputs.build_type, github.sha) }}
|
||||
path: .
|
||||
|
||||
- name: Download previous artifact
|
||||
if: ${{ github.event_name == 'workflow_run' || github.event_name == 'workflow_dispatch' }}
|
||||
uses: dawidd6/action-download-artifact@v21
|
||||
uses: dawidd6/action-download-artifact@v3
|
||||
with:
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: ${{ format('LSB_{0}_{1}_{2}', runner.os, inputs.build_type, github.sha) }}
|
||||
|
|
@ -168,7 +164,7 @@ jobs:
|
|||
if: ${{ inputs.xi_test }}
|
||||
id: xi_test
|
||||
continue-on-error: true
|
||||
run: ./xi_test --keep-going --retry 5 --output tests.ctrf.json
|
||||
run: ./xi_test --keep-going --output tests.ctrf.json
|
||||
|
||||
- name: Publish Test Report
|
||||
if: ${{ !cancelled() && inputs.xi_test }}
|
||||
|
|
@ -189,7 +185,7 @@ jobs:
|
|||
- name: Startup checks
|
||||
if: ${{ inputs.startup_checks }}
|
||||
id: startup_checks
|
||||
uses: nick-fields/retry@v4
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
|
|
|
|||
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
shell: bash
|
||||
steps:
|
||||
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
@ -47,13 +47,10 @@ jobs:
|
|||
shell: bash
|
||||
steps:
|
||||
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate codegen Lua enums
|
||||
run: python -m tools.codegen "$RUNNER_TEMP/codegen-out"
|
||||
|
||||
- name: Run Lua Language Server
|
||||
id: run_lls
|
||||
run: python ./tools/ci/lua_lang_server.py
|
||||
|
|
@ -101,7 +98,7 @@ jobs:
|
|||
build_type: Release
|
||||
test_modules: false
|
||||
multi_process: true
|
||||
xi_test: true
|
||||
xi_test: ${{ !startsWith(matrix.runner, 'macos') }}
|
||||
startup_checks: true
|
||||
|
||||
Docker_Test:
|
||||
|
|
|
|||
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -14,7 +14,6 @@
|
|||
# Build results
|
||||
build/
|
||||
build*/
|
||||
.cpm-cache/
|
||||
lbuild/
|
||||
build_mariadb_32/
|
||||
build_mariadb_64/
|
||||
|
|
@ -219,8 +218,6 @@ ip.txt
|
|||
# Tracy download
|
||||
ext/tracy/
|
||||
tracy.tar.gz
|
||||
tracy*
|
||||
**/*.tracy
|
||||
|
||||
# Valgrind
|
||||
*.memcheck.log
|
||||
|
|
@ -269,7 +266,3 @@ __pycache__
|
|||
sanity_checks_summary.md
|
||||
changed-files.txt
|
||||
clang_tidy_summary.md
|
||||
|
||||
# YAML codegen
|
||||
*.codegen.json
|
||||
*.codegen.lua
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
*.codegen.json
|
||||
*.codegen.lua
|
||||
|
||||
# YAML is formatted by tools/yaml/format.py
|
||||
*.yaml
|
||||
*.yml
|
||||
|
||||
build/
|
||||
build*/
|
||||
cmake-*/
|
||||
out/
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"printWidth": 120,
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
|
|
@ -11,9 +11,6 @@
|
|||
"ms-vscode.cpptools-extension-pack",
|
||||
"ms-vscode.cpptools",
|
||||
"jeff-hykin.better-cpp-syntax",
|
||||
"bierner.github-markdown-preview",
|
||||
"esbenp.prettier-vscode",
|
||||
"redhat.vscode-yaml",
|
||||
"jkillian.custom-local-formatters"
|
||||
"bierner.github-markdown-preview"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
14
.vscode/settings.json
vendored
14
.vscode/settings.json
vendored
|
|
@ -355,20 +355,6 @@
|
|||
"editor.defaultFormatter": "ms-python.black-formatter",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[yaml]": {
|
||||
"editor.defaultFormatter": "jkillian.custom-local-formatters",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"yaml.format.enable": false,
|
||||
"customLocalFormatters.formatters": [
|
||||
{
|
||||
"command": "python tools/yaml/format.py --stdin",
|
||||
"languages": ["yaml"]
|
||||
}
|
||||
],
|
||||
"files.associations": {
|
||||
"algorithm": "cpp",
|
||||
"any": "cpp",
|
||||
|
|
|
|||
|
|
@ -4,35 +4,15 @@ cmake_minimum_required(VERSION 3.25)
|
|||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)
|
||||
|
||||
# On macOS, pin the deployment target to the host OS version (must happen before
|
||||
# project()). Without this, some compilers infer it from the Darwin kernel version
|
||||
# using the pre-macOS-26 numbering scheme (e.g. Homebrew LLVM 20 maps Darwin 25 to
|
||||
# "macOS 16.0" instead of 26), and every link against a Homebrew dylib stamped with
|
||||
# the real version warns:
|
||||
# ld: warning: building for macOS-16.0, but linking with dylib built for newer version 26.0
|
||||
# Overridable as usual via -DCMAKE_OSX_DEPLOYMENT_TARGET or MACOSX_DEPLOYMENT_TARGET.
|
||||
if(CMAKE_HOST_APPLE AND "${CMAKE_OSX_DEPLOYMENT_TARGET}" STREQUAL "" AND "$ENV{MACOSX_DEPLOYMENT_TARGET}" STREQUAL "")
|
||||
execute_process(
|
||||
COMMAND sw_vers -productVersion
|
||||
OUTPUT_VARIABLE host_macos_version
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(REGEX MATCH "^[0-9]+" host_macos_major "${host_macos_version}")
|
||||
if(host_macos_major)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "${host_macos_major}.0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
project(server C CXX)
|
||||
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0069.html
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
|
||||
set(LINKER_LANGUAGE CXX)
|
||||
set(USE_FOLDERS ON)
|
||||
|
||||
|
|
@ -118,6 +98,7 @@ endif()
|
|||
|
||||
# Find MariaDB
|
||||
find_package(MariaDB REQUIRED)
|
||||
find_package(MariaDBCPP REQUIRED)
|
||||
|
||||
# Find ZMQ
|
||||
find_package(ZeroMQ REQUIRED)
|
||||
|
|
@ -132,39 +113,29 @@ find_package(OpenSSLlibcrypto REQUIRED)
|
|||
find_package(OpenSSLlibssl REQUIRED)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
# zstd is sometimes a prereq for binutils
|
||||
# zstd is sometimes a prereq for binutils
|
||||
find_package(Zstd REQUIRED)
|
||||
find_package(Binutils REQUIRED)
|
||||
endif()
|
||||
|
||||
# Link this 'library' to set the c++ standard / compile-time options requested
|
||||
add_library(project_options INTERFACE)
|
||||
target_compile_features(project_options INTERFACE cxx_std_23)
|
||||
|
||||
# Windows-only preprocessor defines for our first-party code ONLY.
|
||||
if(WIN32)
|
||||
target_compile_definitions(project_options INTERFACE
|
||||
NOMINMAX
|
||||
WIN32_LEAN_AND_MEAN
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
endif()
|
||||
target_compile_features(project_options INTERFACE cxx_std_17)
|
||||
|
||||
# Link this 'library' to use the warnings specified in CompilerWarnings.cmake
|
||||
add_library(project_warnings INTERFACE)
|
||||
set_project_warnings(project_warnings)
|
||||
|
||||
add_compile_definitions(
|
||||
# Globally define SOL_ALL_SAFETIES_ON so sol can be included anywhere.
|
||||
SOL_ALL_SAFETIES_ON=1
|
||||
# If SOL_NO_CHECK_NUMBER_PRECISION is defined, turns off number precision and integer
|
||||
# precision fitting when pushing numbers into sol.
|
||||
SOL_NO_CHECK_NUMBER_PRECISION=1
|
||||
SOL_DEFAULT_PASS_ON_ERROR=1
|
||||
SOL_PRINT_ERRORS=0
|
||||
SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_DEBUG
|
||||
XI_CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
|
||||
XI_BUILD_TYPE="$<CONFIG>"
|
||||
# Globally define SOL_ALL_SAFETIES_ON so sol can be included anywhere
|
||||
# If SOL_NO_CHECK_NUMBER_PRECISION is defined, turns off number precision and integer
|
||||
# precision fitting when pushing numbers into sol
|
||||
# add_compile_definitions() comes with CMake 3.12
|
||||
add_definitions(
|
||||
-DSOL_ALL_SAFETIES_ON=1
|
||||
-DSOL_NO_CHECK_NUMBER_PRECISION=1
|
||||
-DSOL_DEFAULT_PASS_ON_ERROR=1
|
||||
-DSOL_PRINT_ERRORS=0
|
||||
-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_DEBUG
|
||||
)
|
||||
|
||||
# For external libs
|
||||
|
|
@ -206,45 +177,6 @@ if (NOT IPC_EXIT_CODE EQUAL 0)
|
|||
message(FATAL_ERROR "Failed to generate IPC stubs")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${Python_EXECUTABLE} -c "import jinja2, jsonschema, yaml"
|
||||
RESULT_VARIABLE CODEGEN_DEPS_EXIT_CODE
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
if(NOT CODEGEN_DEPS_EXIT_CODE EQUAL 0)
|
||||
message(FATAL_ERROR
|
||||
"Codegen requires the Python packages jinja2, jsonschema, and pyyaml, "
|
||||
"but they are not installed for the interpreter CMake selected:\n"
|
||||
" ${Python_EXECUTABLE}\n"
|
||||
"Install them by running this command exactly as shown (the interpreter path "
|
||||
"matters, so the packages land in the environment this build uses):\n"
|
||||
" ${Python_EXECUTABLE} -m pip install -r ${CMAKE_SOURCE_DIR}/tools/requirements.txt"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_target(data_codegen
|
||||
COMMAND ${Python_EXECUTABLE} -m tools.codegen ${CMAKE_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
BYPRODUCTS
|
||||
${CMAKE_BINARY_DIR}/generated/.codegen.stamp
|
||||
${CMAKE_BINARY_DIR}/generated/data/all.h
|
||||
USES_TERMINAL
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
if(NOT EXISTS ${CMAKE_BINARY_DIR}/generated/.codegen.stamp)
|
||||
message(STATUS "Bootstrapping data codegen")
|
||||
execute_process(
|
||||
COMMAND ${Python_EXECUTABLE} -m tools.codegen ${CMAKE_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
RESULT_VARIABLE CODEGEN_EXIT_CODE
|
||||
)
|
||||
if(NOT CODEGEN_EXIT_CODE EQUAL 0)
|
||||
message(FATAL_ERROR "Bootstrap codegen failed")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR}/generated) # Globally include the build/generated directory
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 21,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "Default (RelWithDebInfo)",
|
||||
"description": "Optimized build with debug info. The standard configuration.",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"displayName": "Debug",
|
||||
"description": "Unoptimized build with full debug info.",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "Default (RelWithDebInfo)",
|
||||
"configurePreset": "default",
|
||||
"configuration": "RelWithDebInfo"
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"displayName": "Debug",
|
||||
"configurePreset": "debug",
|
||||
"configuration": "Debug"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -81,7 +81,6 @@ function(set_project_warnings project_name)
|
|||
CLANG_WARNINGS
|
||||
-Wno-nan-infinity-disabled # TODO: fmt triggers this, a combination of the fast-math flag and `isfinite`
|
||||
-Wunused-private-field # warn on unused private fields
|
||||
-Wno-nontrivial-memcall # recastnavigation memsets non-trivially-copyable types (e.g. dtMeshTile)
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
275
cmake/FindMariaDBCPP.cmake
Normal file
275
cmake/FindMariaDBCPP.cmake
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
if(NOT WIN32)
|
||||
message(STATUS "Building MariaDB Connector/C++ from source")
|
||||
CPMAddPackage(
|
||||
NAME mariadb-connector-cpp
|
||||
GITHUB_REPOSITORY zach2good/mariadb-connector-cpp
|
||||
GIT_TAG efffd81c9c9cd806703b84ee7f0913d4de93e2ee
|
||||
DOWNLOAD_ONLY YES
|
||||
)
|
||||
if(mariadb-connector-cpp_ADDED)
|
||||
set(PROJECT_VERSION_MAJOR 0)
|
||||
set(PROJECT_VERSION_MINOR 0)
|
||||
set(PROJECT_VERSION_PATCH 0)
|
||||
|
||||
configure_file(
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Version.h.in
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Version.h
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/maconncpp.def.in
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/maconncpp.def
|
||||
)
|
||||
|
||||
set(MACPP_SOURCES
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDriver.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/DriverManager.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/UrlParser.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDatabaseMetaData.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/HostAddress.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Consts.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SQLString.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbConnection.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbStatement.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBException.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBWarning.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Identifier.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbSavepoint.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SqlStates.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Results.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnType.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnDefinition.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/MasterProtocol.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/QueryProtocol.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/ConnectProtocol.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/ColumnDefinitionCapi.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCache.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCacheKey.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Value.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Utils.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/String.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/NoLogger.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/LoggerFactory.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/ProtocolLoggingProxy.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ParameterHolder.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/options/Options.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/options/DefaultOptions.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/GlobalStateInfo.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/Pools.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/failover/FailoverProxy.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/CredentialPluginLoader.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SelectResultSet.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/SelectResultSetCapi.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/ColumnNameMap.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/io/StandardPacketInputStream.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Charset.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ClientSidePreparedStatement.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/BasePrepareStatement.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbFunctionStatement.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbProcedureStatement.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ServerSidePreparedStatement.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BigDecimalParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BooleanParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteArrayParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DateParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DefaultParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DoubleParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/FloatParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/IntParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/LongParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ULongParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/NullParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ParameterHolder.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ReaderParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ShortParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StreamParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimeParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimestampParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StringParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbPooledConnection.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbParameterMetaData.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbResultSetMetaData.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/CallParameter.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/CallableParameterMetaData.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/Packet.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/Credential.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/LogQueryTool.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ClientPrepareResult.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareResult.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareStatementCache.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationSingle.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationBatch.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationMultiple.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/RowProtocol.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/BinRowProtocolCapi.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/TextRowProtocolCapi.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ExceptionFactory.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/StringImp.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/CArray.cpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SimpleParameterMetaData.cpp
|
||||
)
|
||||
|
||||
# NOTE: Keep this around if we ever want to rebuild the mariadb-connector-cpp library
|
||||
if(WIN32)
|
||||
set(MACPP_SOURCES
|
||||
${MACPP_SOURCES}
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Dll.c
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBConnCpp.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDriver.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/UrlParser.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbDatabaseMetaData.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/HostAddress.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Version.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Consts.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbConnection.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbStatement.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDBWarning.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Protocol.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Identifier.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbSavepoint.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SqlStates.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Results.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnDefinition.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbServerCapabilities.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/MasterProtocol.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/QueryProtocol.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/ConnectProtocol.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/ColumnDefinitionCapi.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCache.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/cache/CallableStatementCacheKey.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Value.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ClassField.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/Utils.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/StateChange.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/String.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/NoLogger.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/LoggerFactory.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/Logger.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/logger/ProtocolLoggingProxy.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ParameterHolder.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/options/Options.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/options/DefaultOptions.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/options/DriverPropertyInfo.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/io/PacketOutputStream.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/io/PacketInputStream.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/io/StandardPacketInputStream.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/CredentialPlugin.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/CredentialPluginLoader.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/GlobalStateInfo.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/Pools.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/pool/Pool.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/failover/FailoverProxy.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Listener.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformation.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Connection.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Statement.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/ResultSet.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/PreparedStatement.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/ParameterMetaData.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/ResultSetMetaData.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/DatabaseMetaData.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/CallableStatement.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/SQLString.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Warning.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Exception.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/jdbccompat.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Driver.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/DriverManager.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/Types.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/buildconf.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp/CArray.hpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SelectResultSet.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/capi/SelectResultSetCapi.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/SelectResultSetPacket.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ColumnType.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/ColumnDefinitionPacket.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/ColumnNameMap.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Charset.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ClientSidePreparedStatement.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/BasePrepareStatement.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbFunctionStatement.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbProcedureStatement.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ServerSidePreparedStatement.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BigDecimalParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/BooleanParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteArrayParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ByteParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DateParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DefaultParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/DoubleParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/FloatParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/IntParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/LongParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ULongParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/NullParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ReaderParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/ShortParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StreamParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimeParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/TimestampParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/parameters/StringParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/Parameters.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbPooledConnection.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbParameterMetaData.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/CallParameter.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/CallableParameterMetaData.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/MariaDbResultSetMetaData.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/Packet.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerStatus.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/credential/Credential.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/LogQueryTool.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/PrepareResult.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ClientPrepareResult.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareResult.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/util/ServerPrepareStatementCache.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationSingle.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationBatch.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/CmdInformationMultiple.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/com/RowProtocol.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/BinRowProtocolCapi.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/protocol/capi/TextRowProtocolCapi.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/ExceptionFactory.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/StringImp.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/CArrayImp.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/SimpleParameterMetaData.h
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/maconncpp.def
|
||||
)
|
||||
endif()
|
||||
add_library(mariadbclientcpp STATIC ${MACPP_SOURCES})
|
||||
target_include_directories(mariadbclientcpp
|
||||
PUBLIC
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include
|
||||
PRIVATE
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/include/conncpp
|
||||
${mariadb-connector-cpp_SOURCE_DIR}/src/
|
||||
)
|
||||
target_link_libraries(mariadbclientcpp PRIVATE mariadbclient)
|
||||
|
||||
set(MARIADBCPP_FOUND TRUE)
|
||||
set(MARIADBCPP_LIBRARY mariadbclientcpp)
|
||||
set(MARIADBCPP_INCLUDE_DIR ${mariadb-connector-cpp_SOURCE_DIR}/include)
|
||||
endif()
|
||||
else() # WIN32
|
||||
message(STATUS "Looking for prebuilt MariaDB Connector/C++")
|
||||
find_library(MARIADBCPP_LIBRARY
|
||||
NAMES
|
||||
mariadbcpp
|
||||
PATHS
|
||||
${PROJECT_SOURCE_DIR}/ext/mariadbcpp/${lib_dir}/
|
||||
)
|
||||
|
||||
set(MARIADBCPP_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/ext/mariadbcpp/include/) # Only look internally
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MariaDBCPP DEFAULT_MSG MARIADBCPP_LIBRARY MARIADBCPP_INCLUDE_DIR)
|
||||
endif()
|
||||
|
||||
message(STATUS "MARIADBCPP_FOUND: ${MARIADBCPP_FOUND}")
|
||||
message(STATUS "MARIADBCPP_LIBRARY: ${MARIADBCPP_LIBRARY}")
|
||||
message(STATUS "MARIADBCPP_INCLUDE_DIR: ${MARIADBCPP_INCLUDE_DIR}")
|
||||
|
||||
add_library(mariadbcpp INTERFACE)
|
||||
target_link_libraries(mariadbcpp INTERFACE ${MARIADBCPP_LIBRARY})
|
||||
target_include_directories(mariadbcpp SYSTEM INTERFACE ${MARIADBCPP_INCLUDE_DIR})
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
|
||||
if(${CMAKE_SOURCE_DIR} MATCHES " +")
|
||||
set(STRIPPED_PATH "")
|
||||
STRING(REGEX REPLACE " +" "_" STRIPPED_PATH "${CMAKE_SOURCE_DIR}")
|
||||
set(STRIPPED_PATH "")
|
||||
STRING(REGEX REPLACE " +" "_" STRIPPED_PATH "${CMAKE_SOURCE_DIR}")
|
||||
|
||||
message(STATUS
|
||||
"Current path: ${CMAKE_SOURCE_DIR}\n"
|
||||
"Suggested path: ${STRIPPED_PATH}\n"
|
||||
"Your path contains spaces, this is not recommended.")
|
||||
message(STATUS
|
||||
"Current path: ${CMAKE_SOURCE_DIR}\n"
|
||||
"Suggested path: ${STRIPPED_PATH}\n"
|
||||
"Your path contains spaces, this is not recommended.")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
|
@ -33,15 +33,3 @@ set(libpath "lib${platform_suffix}")
|
|||
if(WIN32)
|
||||
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# The modern Apple linker (ld_prime, Xcode 15+) warns when the same library
|
||||
# appears more than once on the link line. CMake's dependency propagation
|
||||
# legitimately repeats static libs (historically required by classic ld64),
|
||||
# so the warning is pure noise: silence it where the linker supports the flag.
|
||||
include(CheckLinkerFlag)
|
||||
check_linker_flag(CXX "-Wl,-no_warn_duplicate_libraries" LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
|
||||
if(LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
|
||||
add_link_options("-Wl,-no_warn_duplicate_libraries")
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,14 +1,5 @@
|
|||
# Set a default build type if none was specified
|
||||
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(isMultiConfig)
|
||||
set(CMAKE_CONFIGURATION_TYPES
|
||||
"RelWithDebInfo;Debug;Release;MinSizeRel"
|
||||
CACHE STRING "Available build configurations" FORCE)
|
||||
|
||||
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
|
||||
set(CMAKE_DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
||||
endif()
|
||||
elseif(NOT CMAKE_BUILD_TYPE)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"RelWithDebInfo"
|
||||
|
|
@ -17,11 +8,10 @@ elseif(NOT CMAKE_BUILD_TYPE)
|
|||
set_property(
|
||||
CACHE CMAKE_BUILD_TYPE
|
||||
PROPERTY STRINGS
|
||||
"RelWithDebInfo"
|
||||
"Debug"
|
||||
"Release"
|
||||
"MinSizeRel"
|
||||
)
|
||||
"Debug"
|
||||
"Release"
|
||||
"MinSizeRel"
|
||||
"RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" ON)
|
||||
|
|
@ -51,6 +41,8 @@ if(MSVC)
|
|||
list(APPEND FLAGS_AND_DEFINES
|
||||
-D_CONSOLE
|
||||
-D_MBCS
|
||||
-DNOMINMAX
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
||||
# TODO: This is being overwritten by /Ob0
|
||||
# /Ob2 # Inline Function Expansion
|
||||
|
|
@ -76,7 +68,7 @@ if(MSVC)
|
|||
)
|
||||
endif()
|
||||
|
||||
link_libraries(ws2_32 dbghelp shlwapi winmm shell32 user32)
|
||||
link_libraries(WS2_32 dbghelp Shlwapi)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
|
|
@ -95,48 +87,33 @@ string(REPLACE ";" " " FLAGS_AND_DEFINES_STR "${FLAGS_AND_DEFINES}")
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS_AND_DEFINES_STR}")
|
||||
|
||||
function(set_target_output_directory target)
|
||||
# Run from the repo root: data, scripts, settings and the runtime DLLs all live there.
|
||||
# DEBUGGER_WORKING_DIRECTORY (CMake 4.0+): Ninja and other non-VS generators.
|
||||
# VS_DEBUGGER_WORKING_DIRECTORY: Visual Studio generator (takes precedence there).
|
||||
message(STATUS "Setting output directory for ${target} to ${CMAKE_SOURCE_DIR}")
|
||||
set_target_properties(${target} PROPERTIES
|
||||
DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
|
||||
message(STATUS "${target}: staging build artifact to ${CMAKE_SOURCE_DIR} after build")
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"$<TARGET_FILE:${target}>"
|
||||
"${CMAKE_SOURCE_DIR}/$<TARGET_FILE_NAME:${target}>"
|
||||
VERBATIM)
|
||||
|
||||
if(MSVC)
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "$<$<CONFIG:Debug,RelWithDebInfo>:${CMAKE_COMMAND};-E;copy_if_different;$<TARGET_PDB_FILE:${target}>;${CMAKE_SOURCE_DIR}/$<TARGET_PDB_FILE_NAME:${target}>>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
VERBATIM)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# Under LTO the linker merges codegen objects into temp files and deletes after linking.
|
||||
# We need to preserve those for the next step!
|
||||
# -object_path_lto persists those codegen objects to a real, per-target directory so
|
||||
# dsymutil can gather their DWARF into the .dSYM.
|
||||
if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
||||
set(lto_object_dir "${CMAKE_BINARY_DIR}/lto-objects/${target}")
|
||||
file(MAKE_DIRECTORY "${lto_object_dir}")
|
||||
target_link_options(${target} PRIVATE "-Wl,-object_path_lto,${lto_object_dir}")
|
||||
endif()
|
||||
|
||||
# dsymutil consolidates the DWARF into a self-contained .dSYM that travels with the
|
||||
# binary, and atos picks it up automatically.
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "$<$<CONFIG:Debug,RelWithDebInfo>:dsymutil;$<TARGET_FILE:${target}>;-o;${CMAKE_SOURCE_DIR}/$<TARGET_FILE_NAME:${target}>.dSYM>"
|
||||
COMMAND_EXPAND_LISTS
|
||||
VERBATIM)
|
||||
endif()
|
||||
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_ASAN "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_UBSAN "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_TSAN "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_MSAN "${CMAKE_SOURCE_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_LSAN "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(disable_lto target)
|
||||
target_compile_options(${target} PRIVATE -fno-lto)
|
||||
target_link_options(${target} PRIVATE -fno-lto)
|
||||
endfunction()
|
||||
|
||||
# If we're on Unix and the system is 32-bit (void* is 4-bytes wide),
|
||||
# then there's a good chance we're compiling for Raspberry Pi.
|
||||
# Currently, CMake doesn't detect this properly and needs some help
|
||||
# to link libatomic.
|
||||
# Source: https://gitlab.kitware.com/cmake/cmake/-/issues/21174
|
||||
#
|
||||
# TODO: Use include(CheckCXXSourceCompiles) to make this check better.
|
||||
if(UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -latomic")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.allegiance
|
||||
|
||||
values:
|
||||
mob: 0
|
||||
player: 1
|
||||
san_doria: 2
|
||||
bastok: 3
|
||||
windurst: 4
|
||||
wyverns: 5
|
||||
griffons: 6
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.animation
|
||||
|
||||
values:
|
||||
none: 0
|
||||
attack: 1
|
||||
despawn: 2
|
||||
death: 3
|
||||
event: 4
|
||||
chocobo: 5
|
||||
fishing: 6
|
||||
open_door: 8
|
||||
close_door: 9
|
||||
elevator_up: 10
|
||||
elevator_down: 11
|
||||
fishing_npc: 32
|
||||
healing: 33
|
||||
fishing_fish: 38
|
||||
fishing_caught: 39
|
||||
fishing_rod_break: 40
|
||||
fishing_line_break: 41
|
||||
fishing_monster: 42
|
||||
fishing_stop: 43
|
||||
synth: 44
|
||||
sit: 47
|
||||
ranged: 48
|
||||
fishing_start: 50
|
||||
new_fishing_start: 56
|
||||
new_fishing_fish: 57
|
||||
new_fishing_caught: 58
|
||||
new_fishing_rod_break: 59
|
||||
new_fishing_line_break: 60
|
||||
new_fishing_monster: 61
|
||||
new_fishing_stop: 62
|
||||
# 63 through 73 are used with /sitchair
|
||||
sitchair_0: 63
|
||||
sitchair_1: 64
|
||||
sitchair_2: 65
|
||||
sitchair_3: 66
|
||||
sitchair_4: 67
|
||||
sitchair_5: 68
|
||||
sitchair_6: 69
|
||||
sitchair_7: 70
|
||||
sitchair_8: 71
|
||||
sitchair_9: 72
|
||||
sitchair_10: 73
|
||||
mount: 85
|
||||
trust: 90 # trust NPC spawn-in animation
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.attackType
|
||||
|
||||
values:
|
||||
none: 0
|
||||
physical: 1
|
||||
magical: 2
|
||||
ranged: 3
|
||||
breath: 4
|
||||
special: 5
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.behavior
|
||||
|
||||
values:
|
||||
none: 0x000
|
||||
no_despawn: 0x001 # mob does not despawn on death
|
||||
standback: 0x002 # mob will standback forever
|
||||
raisable: 0x004 # mob can be raised via Raise spells
|
||||
no_assist: 0x008 # mob can not be targeted by helpful magic from players (cure, protect, etc)
|
||||
aggro_ambush: 0x200 # mob aggroes by ambush
|
||||
no_turn: 0x400 # mob does not turn to face target
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.claimType
|
||||
|
||||
values:
|
||||
exclusive: 0 # Regular exclusive claim behavior. Only one entity and related group can attack.
|
||||
non_exclusive: 1 # Regular claim behavior but multiple unrelated entities can attack and compete for claim. Rewards distributed to last claiming entity.
|
||||
unclaimable: 2 # Mob cannot be claimed. Multiple unrelated entities can attack. Rewards will not be distributed.
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.damageType
|
||||
|
||||
values:
|
||||
none: 0
|
||||
piercing: 1
|
||||
slashing: 2
|
||||
blunt: 3
|
||||
hand_to_hand: 4
|
||||
elemental: 5
|
||||
fire: 6
|
||||
ice: 7
|
||||
wind: 8
|
||||
earth: 9
|
||||
thunder: 10
|
||||
water: 11
|
||||
light: 12
|
||||
dark: 13
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.detects
|
||||
|
||||
values:
|
||||
none: 0x000
|
||||
sight: 0x001
|
||||
hearing: 0x002
|
||||
sight_and_hearing: 0x003
|
||||
lowhp: 0x004
|
||||
none1: 0x008
|
||||
none2: 0x010
|
||||
magic: 0x020
|
||||
weaponskill: 0x040
|
||||
jobability: 0x080
|
||||
scent: 0x100
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.ecosystem
|
||||
|
||||
values:
|
||||
unclassified: 0
|
||||
amorph: 1
|
||||
aquan: 2
|
||||
arcana: 3
|
||||
archaic_machine: 4
|
||||
beast: 5
|
||||
beastmen: 6
|
||||
bird: 7
|
||||
demon: 8
|
||||
dragon: 9
|
||||
elemental: 10
|
||||
empty: 11
|
||||
humanoid: 12
|
||||
lizard: 13
|
||||
luminian: 14
|
||||
luminion: 15
|
||||
plantoid: 16
|
||||
supreme_beings: 17
|
||||
undead: 18
|
||||
vermin: 19
|
||||
voragean: 20
|
||||
structures: 21
|
||||
weapons: 22
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.effectOverwrite
|
||||
|
||||
values:
|
||||
equal_higher: 0 # only overwrite if equal or higher (tier, power)
|
||||
higher: 1 # only overwrite if higher (tier, power)
|
||||
never: 2 # never overwrite
|
||||
always: 3 # always overwrite no matter
|
||||
ignore_duplicate: 4 # ignore dupes
|
||||
tier_higher: 5 # only overwrite if tier is higher (regardless of power)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.element
|
||||
|
||||
values:
|
||||
none: 0
|
||||
fire: 1
|
||||
ice: 2
|
||||
wind: 3
|
||||
earth: 4
|
||||
thunder: 5
|
||||
water: 6
|
||||
light: 7
|
||||
dark: 8
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint32_t
|
||||
lua:
|
||||
table: xi.entityFlags
|
||||
|
||||
values:
|
||||
none: 0x000
|
||||
info_icon: 0x001 # (I) Icon next to name
|
||||
# TODO: Flags 0x002, 0x004 and 0x008 do different things for different entities.
|
||||
# : It isn't one-size-fits-all, and different combinations may do different things.
|
||||
# : It'll need to be researched more.
|
||||
# alt_appearance: 0x002
|
||||
hide_name: 0x008
|
||||
call_for_help: 0x020
|
||||
hide_model: 0x080
|
||||
hide_hp: 0x100
|
||||
untargetable: 0x800
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint32_t
|
||||
lua:
|
||||
table: xi.immunity
|
||||
|
||||
values:
|
||||
none: 0x00000000
|
||||
addle: 0x00000001
|
||||
gravity: 0x00000002
|
||||
bind: 0x00000004
|
||||
stun: 0x00000008
|
||||
silence: 0x00000010
|
||||
paralyze: 0x00000020
|
||||
blind: 0x00000040
|
||||
slow: 0x00000080
|
||||
poison: 0x00000100
|
||||
elegy: 0x00000200
|
||||
requiem: 0x00000400
|
||||
light_sleep: 0x00000800
|
||||
dark_sleep: 0x00001000
|
||||
aspir: 0x00002000
|
||||
terror: 0x00004000
|
||||
dispel: 0x00008000
|
||||
petrify: 0x00010000
|
||||
plague: 0x00020000
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
case: screaming
|
||||
lua:
|
||||
table: xi.job
|
||||
|
||||
values:
|
||||
none: 0
|
||||
war: 1
|
||||
mnk: 2
|
||||
whm: 3
|
||||
blm: 4
|
||||
rdm: 5
|
||||
thf: 6
|
||||
pld: 7
|
||||
drk: 8
|
||||
bst: 9
|
||||
brd: 10
|
||||
rng: 11
|
||||
sam: 12
|
||||
nin: 13
|
||||
drg: 14
|
||||
smn: 15
|
||||
blu: 16
|
||||
cor: 17
|
||||
pup: 18
|
||||
dnc: 19
|
||||
sch: 20
|
||||
geo: 21
|
||||
run: 22
|
||||
mon: 23 # NOTE: MON is not a full job
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.latent
|
||||
|
||||
values:
|
||||
hp_under_percent: 0 # hp less than or equal to % - PARAM: HP PERCENT
|
||||
hp_over_percent: 1 # hp more than % - PARAM: HP PERCENT
|
||||
hp_under_tp_under_100: 2 # hp less than or equal to %, tp under 100 - PARAM: HP PERCENT
|
||||
hp_over_tp_under_100: 3 # hp more than %, tp over 100 - PARAM: HP PERCENT
|
||||
mp_under_percent: 4 # mp less than or equal to % - PARAM: MP PERCENT
|
||||
mp_under: 5 # mp less than # - PARAM: MP #
|
||||
tp_under: 6 # tp under # and during WS - PARAM: TP VALUE
|
||||
tp_over: 7 # tp over # - PARAM: TP VALUE
|
||||
subjob: 8 # subjob - PARAM: JOBTYPE
|
||||
pet_id: 9 # pettype - PARAM: PETID
|
||||
weapon_drawn: 10 # weapon drawn
|
||||
weapon_sheathed: 11 # weapon sheathed
|
||||
signet_bonus: 12 # While in conquest region and engaged to an even match or less target
|
||||
status_effect_active: 13 # status effect on player - PARAM: EFFECTID
|
||||
no_food_active: 14 # no food effects active on player
|
||||
party_members: 15 # party size # - PARAM: # OF MEMBERS
|
||||
party_members_in_zone: 16 # party size # and members in zone - PARAM: # OF MEMBERS
|
||||
sanction_regen_bonus: 17 # While in besieged region and HP is less than PARAM%
|
||||
sanction_refresh_bonus: 18 # While in besieged region and MP is less than PARAM%
|
||||
sigil_regen_bonus: 19 # While in campaign region and HP is less than PARAM%
|
||||
sigil_refresh_bonus: 20 # While in campaign region and MP is less than PARAM%
|
||||
avatar_in_party: 21 # party has a specific avatar - PARAM: same as globals/pets.lua (21 for any avatar)
|
||||
job_in_party: 22 # party has job - PARAM: JOBTYPE
|
||||
zone: 23 # in zone - PARAM: zoneid
|
||||
synth_trainee: 24 # synth skill under 40 + no support: PARAM: 48: FISH, 49: WOOD, 50: SMITH, 51: GOLDSMITH, 52: CLOTH, 53: LEATHER, 54: BONE, 55: ALCHEMY, 56: COOKING
|
||||
song_roll_active: 25 # any song or roll active
|
||||
time_of_day: 26 # PARAM: 0: DAYTIME 1: NIGHTTIME 2: DUSK-DAWN
|
||||
hour_of_day: 27 # PARAM: 1: NEW DAY, 2: DAWN, 3: DAY, 4: DUSK, 5: EVENING, 6: DEAD OF NIGHT
|
||||
firesday: 28
|
||||
earthsday: 29
|
||||
watersday: 30
|
||||
windsday: 31
|
||||
darksday: 32
|
||||
iceday: 34
|
||||
lightningsday: 35
|
||||
lightsday: 36
|
||||
moon_phase: 37 # PARAM: 0: New Moon, 1: Waxing Crescent, 2: First Quarter, 3: Waxing Gibbous, 4: Full Moon, 5: Waning Gibbous, 6: Last Quarter, 7: Waning Crescent
|
||||
job_multiple: 38 # PARAM: 0: ODD, 2: EVEN, 3-X: DIVISOR
|
||||
job_multiple_at_night: 39 # PARAM: 0: ODD, 2: EVEN, 3-X: DIVISOR
|
||||
equipped_in_slot: 40 # When item is equipped in the specified slot (e.g. Dweomer Knife, Erlking's Sword, etc.) PARAM: slotID
|
||||
during_ws: 41 # During WS
|
||||
weather_condition: 42 # See Weather.h for WEATHER enum
|
||||
weapon_drawn_hp_under: 43 # PARAM: HP PERCENT
|
||||
nation_citizen: 44 # Triggered by player being citizen of nation matching param: 0 San d'Oria, 1 Bastok, 2 Windurst
|
||||
mp_under_visible_gear: 45 # mp less than or equal to %, calculated using MP bonuses from visible gear only
|
||||
hp_over_visible_gear: 46 # hp more than or equal to %, calculated using HP bonuses from visible gear only
|
||||
weapon_broken: 47
|
||||
in_dynamis: 48
|
||||
food_active: 49 # food effect (foodId) active - PARAM: FOOD ITEMID
|
||||
job_level_below: 50 # PARAM: level
|
||||
job_level_above: 51 # PARAM: level
|
||||
weather_element: 52 # PARAM: 0: NONE, 1: FIRE, 2: ICE, 3: WIND 4: EARTH, 5: THUNDER, 6: WATER, 7: LIGHT, 8: DARK
|
||||
nation_control: 53 # checks if player region is under nation's control - PARAM: 0: Under own nation's control, 1: Outside own nation's control
|
||||
zone_home_nation: 54 # in zone and citizen of nation (aketons)
|
||||
mp_over: 55 # mp greater than # - PARAM: MP #
|
||||
weapon_drawn_mp_over: 56 # while weapon is drawn and mp greater than # - PARAM: MP #
|
||||
eleven_roll_active: 57 # corsair roll of 11 active
|
||||
in_assault: 58 # is in an Instance battle in a TOAU zone
|
||||
vs_ecosystem: 59 # Vs. Specific Ecosystem ID (e.g. Vs. Plantoid: Accuracy+3)
|
||||
vs_species: 60 # Vs. Specific Species ID (e.g. Vs. Korrigan: Accuracy+3)
|
||||
vs_family: 61 # Vs. Specific Family ID (e.g. Vs. Mandragora: Accuracy+3)
|
||||
mainjob: 62 # mainjob - PARAM: JOBTYPE
|
||||
in_adoulin: 63
|
||||
in_garrison: 64 # while in an active Garrison
|
||||
sanction_food_bonus: 65 # While in besieged region
|
||||
sigil_food_bonus: 66 # While in campaign region
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.mobMod
|
||||
|
||||
values:
|
||||
none: 0
|
||||
gil_min: 1 # minimum gil drop -- spawn mod only
|
||||
gil_max: 2 # maximum gil drop -- spawn mod only
|
||||
mp_base: 3 # Give mob mp. Used for mobs that are not mages, wyverns, avatars
|
||||
sight_range: 4 # sight range
|
||||
sound_range: 5 # sound range
|
||||
buff_chance: 6 # % chance to buff (combat only)
|
||||
ga_chance: 7 # % chance to use -ga spell
|
||||
heal_chance: 8 # % chance to use heal
|
||||
hp_heal_chance: 9 # can cast cures below this HP %
|
||||
sublink: 10 # Sub link group. Enables mobs from different families to link if they share a SUBLINK value.
|
||||
link_radius: 11 # link radius
|
||||
sees_through_illusion: 12 # Mob can see through the Illusion effect that grants effects similar to Sneak & Invisible without this mod and allows aggro (see Viscious Liquid in mamook)
|
||||
severe_spell_chance: 13 # % chance to use a severe spell like death or impact
|
||||
skill_list: 14 # uses given mob skill list
|
||||
mug_gil: 15 # amount gil carried for mugging
|
||||
detection: 16 # Overrides mob family's detection method. In order to set to override to none an unused bit must be set such as xi::Detects::None1.
|
||||
no_despawn: 17 # do not despawn when too far from spawn. Gob Diggers have this.
|
||||
var: 18 # temp var for whatever. Gets cleared on spawn
|
||||
can_shield_block: 19 # toggle shield use for mobs without physical shields (trusts)
|
||||
no_h2h_penalty: 20 # Disables H2H penalty in base damage calculation when set to non-zero
|
||||
pet_spell_list: 21 # set pet spell list
|
||||
na_chance: 22 # % chance to cast -na
|
||||
immunity: 23 # immune to set status effects. This only works from the db, not scripts
|
||||
gradual_rage: 24 # (!) TODO: NOT YET IMPLEMENTED -- gradually rages
|
||||
build_resist: 25 # (!) TODO: NOT YET IMPLEMENTED -- builds resistance to given effects
|
||||
superlink: 26 # super link group. Only use this in scripts! Must be defined in onMobInitialize if relevant mobs are different families
|
||||
spell_list: 27 # set spell list
|
||||
exp_bonus: 28 # bonus exp (bonus / 100) negative values reduce exp.
|
||||
assist: 29 # mobs will assist me
|
||||
special_skill: 30 # give special skill
|
||||
roam_distance: 31 # distance allowed to roam from spawn
|
||||
dont_roam_home: 32 # Allow mobs to roam any distance from spawn. Useful for mobs with scripted roaming behavior.
|
||||
special_cool: 33 # cool down for special
|
||||
magic_cool: 34 # cool down for magic
|
||||
standback_cool: 35 # cool down time for standing back (casting spell while not in attack range)
|
||||
roam_cool: 36 # cool down time in seconds after roaming
|
||||
always_aggro: 37 # aggro regardless of level. Spheroids
|
||||
no_drops: 38 # If set monster cannot drop any items, not even seals.
|
||||
share_pos: 39 # share a pos with another mob (eald'narche exoplates)
|
||||
teleport_cd: 40 # cooldown for teleport abilities (tarutaru AA, angra mainyu, eald'narche)
|
||||
teleport_start: 41 # mobskill ID to begin teleport
|
||||
teleport_end: 42 # mobskill ID to end teleport
|
||||
teleport_type: 43 # teleport type - 1: on cooldown, 2 - to close distance
|
||||
dual_wield: 44 # enables a mob to use their offhand in attacks
|
||||
add_effect: 45 # enables additional effect script to process on mobs attacks
|
||||
auto_spikes: 46 # enables additional effect script to process when mob is attacked
|
||||
spawn_leash: 47 # forces a mob to not move farther from its spawn than its leash distance
|
||||
share_target: 48 # mob always targets same target as ID in this var
|
||||
check_as_nm: 49 # If set , mob will check as a NM
|
||||
roam_reset_facing: 50 # Resume facing the default spawn rotation after roaming home.
|
||||
roam_turns: 51 # Maximum amount of turns during a roam
|
||||
roam_rate: 52 # Roaming frequency. roam_cool - rand(roam_cool / (roam_rate / 10))
|
||||
behavior: 53 # Add behaviors to mob
|
||||
gil_bonus: 54 # Allow mob to drop gil. Multiplier to gil dropped by mob (bonus / 100) * total
|
||||
idle_despawn: 55 # Time (in seconds) to despawn after being idle
|
||||
hp_standback: 56 # mob will always standback with hp % higher to value
|
||||
magic_delay: 57 # Amount of seconds mob waits before casting first spell
|
||||
special_delay: 58 # Amount of seconds mob waits before using first special
|
||||
base_damage_modifier: 59 # Add a flat modifer mob a mob's base damage. This is subject to multiplication by MOBMOD_BASE_DAMAGE_MULTIPLIER.
|
||||
spawn_animationsub: 60 # reset animationsub to this on spawn
|
||||
hp_scale: 61 # Scale the mobs max HP. ( hp_scale / 100 ) * maxhp
|
||||
no_standback: 62 # Mob will never standback
|
||||
attack_skill_list: 63 # skill list to use in place of regular attacks
|
||||
charmable: 64 # mob is charmable
|
||||
no_move: 65 # Mob will not be able to move
|
||||
multi_hit: 66 # Mob will have as many swings as defined.
|
||||
no_aggro: 67 # If set, mob cannot aggro until unset.
|
||||
alli_hate: 68 # Range around target to add alliance member to enmity list.
|
||||
no_link: 69 # If set, mob cannot link until unset.
|
||||
no_rest: 70 # Mob cannot regain hp (e.g. re-burrowing antlions during ENM).
|
||||
leader: 71 # Used for mob following. Positive number is how many followers a leader has. A negative number is the distance from this mob ID to the leader ID.
|
||||
magic_range: 72 # magic aggro range
|
||||
target_distance_offset: 73 # Adjusts how close a mob will move to it's target. 12 = 1.2 yalm. Positive values to go closer, negative farther.
|
||||
one_way_linking: 74 # Will link with other mobs in its party (typically the same mob family) while roaming, but will not let others link with it once engaged
|
||||
can_parry: 75 # Check if a mob is allowed to have parry rank (Rank Value 1-5)
|
||||
no_widescan: 76 # Disables widescan for a specific mob
|
||||
trust_distance: 77 # TRUSTS ONLY: Set movement type/distance. See trust.lua for details.
|
||||
standback_range: 78 # Applies a specific standback range for the mob
|
||||
cannot_guard: 79 # Check if the mob does not guard(despite being a MNK or PUP mob)
|
||||
skip_allegiance_check: 80 # Skip the allegiance check for valid target (allows for example a mob to cast a TARGET_ENEMY spell on itself)
|
||||
ability_response: 81 # Mob can respond to player ability use with onPlayerAbilityUse()
|
||||
run_speed_mult: 82 # Multiplier for the speed of a mob while running (generally when the target is out of range) 100 = 1.00x
|
||||
claim_type: 83 # Changes the claim behavior of the mob. See xi::ClaimType enum.
|
||||
no_spell_cost: 84 # Mob does not use MP when casting spells
|
||||
astral_pet_offset: 85 # If non-zero, defines the offset from main mob's ID for astral flow (if zero, will assume offset of 2)
|
||||
base_damage_multiplier: 86 # Multiplies the mob's base damage. Example: 150 = x1.5. MOBMOD_DAMAGE_OFFSET/MOBMOD_RANGED_DAMAGE_OFFSET are not subject to multiplication.
|
||||
damage_offset: 87 # Adds or subtracts the mob's base damage offset.
|
||||
ranged_damage_offset: 88 # Adds or subtracts the mob's ranged base damage offset.
|
||||
avatar_petid: 89 # A value from xi.petId to select model/ability from when owner uses astral flow
|
||||
avatar_astral_delay: 90 # Number of milliseconds to delay AF after avatar spawn
|
||||
h2h_single_swing: 91 # Mob will have only one swing per attack even as MNK with H2H skill
|
||||
aoe_hit_all: 92 # Mob AoE can hit any player regardless of enmity
|
||||
ranged_attack_range: 93 # Max range for ranged auto attacks. Mob will move closer if target is beyond this range.
|
||||
follow_leash_range: 94 # Distance the leader can walk before their followers start moving. Applied to followers.
|
||||
follow_stop_range: 95 # Distance the followers attempt to stop at once their leader stops moving. Applied to followers.
|
||||
trust_shield_size: 96 # TRUSTS ONLY: Set the size of the mob's shield. 3 = Default size, only used for trusts that use shields.
|
||||
bodyguard: 97 # Charmed mob defends its master similar to an avatar. (Maiden's Virelai)
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.mobType
|
||||
|
||||
values:
|
||||
normal: 0x00
|
||||
unused: 0x01 # available for use
|
||||
notorious: 0x02
|
||||
fished: 0x04
|
||||
called: 0x08
|
||||
battlefield: 0x10
|
||||
event: 0x20
|
||||
1275
data/enums/mod.yaml
1275
data/enums/mod.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -1,14 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.nameVis
|
||||
|
||||
values:
|
||||
none: 0x00
|
||||
icon: 0x01 # (I) Icon next to name
|
||||
hide_name: 0x08
|
||||
ghost_phase: 0x80
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.roamFlag
|
||||
|
||||
values:
|
||||
none: 0x000
|
||||
none0: 0x001
|
||||
none1: 0x002
|
||||
none2: 0x004
|
||||
none3: 0x008
|
||||
none4: 0x010
|
||||
none5: 0x020
|
||||
worm: 0x040 # pop up and down when moving
|
||||
ambush: 0x080 # stays hidden until someone comes close (antlion)
|
||||
scripted: 0x100 # calls lua method for roaming logic
|
||||
ignore: 0x200 # ignore all hate, except linking hate
|
||||
stealth: 0x400 # stays name hidden and untargetable until someone comes close (chigoe)
|
||||
follow: 0x800 # follows a player when sighted for a little while
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.skill
|
||||
|
||||
values:
|
||||
# Combat Skills
|
||||
none: 0
|
||||
hand_to_hand: 1
|
||||
dagger: 2
|
||||
sword: 3
|
||||
great_sword: 4
|
||||
axe: 5
|
||||
great_axe: 6
|
||||
scythe: 7
|
||||
polearm: 8
|
||||
katana: 9
|
||||
great_katana: 10
|
||||
club: 11
|
||||
staff: 12
|
||||
# 13-21 unused
|
||||
automaton_melee: 22
|
||||
automaton_ranged: 23
|
||||
automaton_magic: 24
|
||||
archery: 25
|
||||
marksmanship: 26
|
||||
throwing: 27
|
||||
# Defensive Skills
|
||||
guard: 28
|
||||
evasion: 29
|
||||
shield: 30
|
||||
parry: 31
|
||||
# Magic Skills
|
||||
divine_magic: 32
|
||||
healing_magic: 33
|
||||
enhancing_magic: 34
|
||||
enfeebling_magic: 35
|
||||
elemental_magic: 36
|
||||
dark_magic: 37
|
||||
summoning_magic: 38
|
||||
ninjutsu: 39
|
||||
singing: 40
|
||||
string_instrument: 41
|
||||
wind_instrument: 42
|
||||
blue_magic: 43
|
||||
geomancy: 44
|
||||
handbell: 45
|
||||
# 46-47 unused
|
||||
# Crafting Skills
|
||||
fishing: 48
|
||||
woodworking: 49
|
||||
smithing: 50
|
||||
goldsmithing: 51
|
||||
clothcraft: 52
|
||||
leathercraft: 53
|
||||
bonecraft: 54
|
||||
alchemy: 55
|
||||
cooking: 56
|
||||
synergy: 57
|
||||
# Other Skills
|
||||
rid: 58
|
||||
dig: 59
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.spawnAnimation
|
||||
|
||||
values:
|
||||
normal: 0
|
||||
special: 1
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.spawnType
|
||||
|
||||
values:
|
||||
normal: 0x00 # 00:00-24:00
|
||||
at_night: 0x01 # 20:00-04:00
|
||||
at_evening: 0x02 # 18:00-06:00
|
||||
weather: 0x04
|
||||
fog: 0x08 # 02:00-07:00
|
||||
moonphase: 0x10
|
||||
lottery: 0x20
|
||||
windowed: 0x40
|
||||
scripted: 0x80 # scripted spawn
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint8_t
|
||||
lua:
|
||||
table: xi.status
|
||||
|
||||
values:
|
||||
normal: 0
|
||||
update: 1
|
||||
disappear: 2
|
||||
invisible: 3
|
||||
status_4: 4
|
||||
cutscene_only: 6
|
||||
status_18: 18
|
||||
shutdown: 20
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint32_t
|
||||
lua:
|
||||
table: xi.effectFlag
|
||||
|
||||
values:
|
||||
none: 0x00000000
|
||||
dispelable: 0x00000001
|
||||
erasable: 0x00000002
|
||||
attack: 0x00000004
|
||||
empathy: 0x00000008
|
||||
damage: 0x00000010
|
||||
death: 0x00000020
|
||||
magic_begin: 0x00000040
|
||||
magic_end: 0x00000080
|
||||
on_zone: 0x00000100
|
||||
no_loss_message: 0x00000200
|
||||
invisible: 0x00000400
|
||||
detectable: 0x00000800
|
||||
no_rest: 0x00001000
|
||||
prevent_action: 0x00002000
|
||||
waltzable: 0x00004000
|
||||
food: 0x00008000
|
||||
song: 0x00010000
|
||||
roll: 0x00020000
|
||||
synth_support: 0x00040000
|
||||
confrontation: 0x00080000
|
||||
logout: 0x00100000
|
||||
bloodpact: 0x00200000
|
||||
on_jobchange: 0x00400000
|
||||
no_cancel: 0x00800000
|
||||
influence: 0x01000000
|
||||
offline_tick: 0x02000000
|
||||
aura: 0x04000000
|
||||
hide_timer: 0x08000000
|
||||
on_zone_pathos: 0x10000000
|
||||
always_expiring: 0x20000000
|
||||
on_attack: 0x40000000
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.weather
|
||||
|
||||
values:
|
||||
none: 0
|
||||
sunshine: 1
|
||||
clouds: 2
|
||||
fog: 3
|
||||
hot_spell: 4
|
||||
heat_wave: 5
|
||||
rain: 6
|
||||
squall: 7
|
||||
dust_storm: 8
|
||||
sand_storm: 9
|
||||
wind: 10
|
||||
gales: 11
|
||||
snow: 12
|
||||
blizzards: 13
|
||||
thunder: 14
|
||||
thunderstorms: 15
|
||||
auroras: 16
|
||||
stellar_glare: 17
|
||||
gloom: 18
|
||||
darkness: 19
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.zoneMisc
|
||||
|
||||
values:
|
||||
none: 0x0000 # Able to be used in any area
|
||||
escape: 0x0001 # Ability to use Escape Spell
|
||||
fellow: 0x0002 # Ability to summon Fellow NPC
|
||||
mount: 0x0004 # Ability to use Chocobos and mounts
|
||||
mazurka: 0x0008 # Ability to use Mazurka Spell
|
||||
tractor: 0x0010 # Ability to use Tractor Spell
|
||||
mogmenu: 0x0020 # Ability to communicate with Nomad Moogle (menu access mog house)
|
||||
costume: 0x0040 # Ability to use a Costumes
|
||||
pet: 0x0080 # Ability to summon Pets
|
||||
treasure: 0x0100 # Presence in the global zone TreasurePool
|
||||
auction_house: 0x0200 # Ability to use the auction house
|
||||
yell: 0x0400 # Send and receive /yell commands
|
||||
trust: 0x0800 # Ability to summon Trust NPC
|
||||
los_player_block: 0x1000 # Players can't use magic/JAs through walls if this is set
|
||||
los_off: 0x2000 # Zone should not have LoS checks
|
||||
assist: 0x4000 # Send and receive /assiste, /assistj commands
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# yaml-language-server: $schema=../schemas/enums/_enum.schema.json
|
||||
|
||||
meta:
|
||||
flags: true
|
||||
cpp:
|
||||
underlying: uint16_t
|
||||
lua:
|
||||
table: xi.zoneType
|
||||
|
||||
values:
|
||||
unknown: 0x0000
|
||||
city: 0x0001
|
||||
outdoors: 0x0002
|
||||
dungeon: 0x0004
|
||||
signet: 0x0008
|
||||
sanction: 0x0010
|
||||
sigil: 0x0020
|
||||
ionis: 0x0040
|
||||
dynamis: 0x0080
|
||||
instanced: 0x0100
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "_meta.schema.json",
|
||||
"title": "Data-file codegen metadata",
|
||||
"description": "Optional top-level `meta:` block in data yamls. Carries directives that drive codegen.",
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"properties": {
|
||||
"enum": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["cpp"],
|
||||
"description": "Emit a typed enum derived from a top-level section of the data file.",
|
||||
"properties": {
|
||||
"cpp": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["underlying", "class"],
|
||||
"properties": {
|
||||
"underlying": { "type": "string" },
|
||||
"class": { "type": "string", "pattern": "^[A-Z][A-Za-z0-9]*$" },
|
||||
"case": { "type": "string", "enum": ["pascal", "screaming"], "default": "pascal" }
|
||||
}
|
||||
},
|
||||
"lua": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"properties": {
|
||||
"table": { "type": "string", "pattern": "^xi\\.[A-Za-z][A-Za-z0-9_]*$" }
|
||||
}
|
||||
},
|
||||
"section": {
|
||||
"type": "string",
|
||||
"description": "Which top-level YAML section to walk. Defaults to the filename."
|
||||
},
|
||||
"name_from": {
|
||||
"type": "string",
|
||||
"description": "Dot-path inside each entry to a string that gets slugged into the enum value name (e.g., `name.en`). When set, the YAML key is treated as the integer id."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "_enum.schema.json",
|
||||
"title": "Enum source",
|
||||
"description": "Meta-schema for data/enums/*.yaml. Each file declares a typed enum: a `meta` block describing the C++/Lua surface, and a `values` map of name -> integer.",
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["meta", "values"],
|
||||
|
||||
"properties": {
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["cpp"],
|
||||
"properties": {
|
||||
"flags": {
|
||||
"description": "True if values are bitmask flags.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"cpp": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["underlying"],
|
||||
"properties": {
|
||||
"underlying": {
|
||||
"description": "C++ underlying integer type for the enum class.",
|
||||
"type": "string",
|
||||
"enum": ["int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t"]
|
||||
},
|
||||
"class": {
|
||||
"description": "Generated C++ enum class name (PascalCase).",
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z][A-Za-z0-9]*$"
|
||||
},
|
||||
"case": {
|
||||
"description": "Case style for generated enum value names. `pascal` (default): `War`, `MysteryBox`. `screaming`: `WAR`, `MYSTERY_BOX`.",
|
||||
"type": "string",
|
||||
"enum": ["pascal", "screaming"],
|
||||
"default": "pascal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lua": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"properties": {
|
||||
"table": {
|
||||
"description": "Lua table path the values are exported under. Example: `xi.itemFlag`.",
|
||||
"type": "string",
|
||||
"pattern": "^xi\\.[A-Za-z][A-Za-z0-9_]*$"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"description": "Map of value name -> integer. Names must be snake_case and unique. Integers may be decimal or hex (0xNN).",
|
||||
"type": "object",
|
||||
"minProperties": 1,
|
||||
"propertyNames": { "pattern": "^[a-z][a-z0-9_]*$" },
|
||||
"additionalProperties": { "type": "integer" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "status_effects.schema.json",
|
||||
"title": "StatusEffects",
|
||||
"description": "Schema for data/status_effects.yaml.",
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["status_effects"],
|
||||
|
||||
"properties": {
|
||||
"meta": { "$ref": "_meta.schema.json" },
|
||||
"status_effects": {
|
||||
"type": "object",
|
||||
"description": "Status effects.",
|
||||
"propertyNames": { "pattern": "^[a-z][a-z0-9_]*$" },
|
||||
"additionalProperties": { "$ref": "#/$defs/status_effect" }
|
||||
}
|
||||
},
|
||||
|
||||
"$defs": {
|
||||
"status_effect": {
|
||||
"type": "object",
|
||||
"unevaluatedProperties": false,
|
||||
"required": ["id"],
|
||||
"properties": {
|
||||
"id": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Override for the Lua script lookup name. Defaults to the YAML key."
|
||||
},
|
||||
"flags": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "enums/status_effect_flag.codegen.json" },
|
||||
"uniqueItems": true,
|
||||
"default": []
|
||||
},
|
||||
"exclusion_group": {
|
||||
"$ref": "enums/status_effect.codegen.json",
|
||||
"description": "Applying this effect removes all other effects sharing the same group (the group's representative effect). e.g. all spikes share blaze_spikes."
|
||||
},
|
||||
"negative": { "$ref": "enums/status_effect.codegen.json" },
|
||||
"overwrite": { "$ref": "enums/effect_overwrite.codegen.json" },
|
||||
"block": { "$ref": "enums/status_effect.codegen.json" },
|
||||
"remove": { "$ref": "enums/status_effect.codegen.json" },
|
||||
"element": { "$ref": "enums/element.codegen.json" },
|
||||
"min_duration": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
||||
"sort_key": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
||||
"wear_off_message_id": { "type": "integer", "minimum": 0, "maximum": 65535 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -3,7 +3,7 @@
|
|||
########
|
||||
# Base #
|
||||
########
|
||||
ARG BASE_TAG=3.24
|
||||
ARG BASE_TAG=3.22
|
||||
FROM --platform=$BUILDPLATFORM alpine:$BASE_TAG AS base
|
||||
|
||||
# Install runtime dependencies.
|
||||
|
|
@ -12,7 +12,6 @@ apk --update-cache add \
|
|||
bash \
|
||||
binutils \
|
||||
git \
|
||||
libdwarf \
|
||||
lua5.1-dev \
|
||||
luajit \
|
||||
mariadb-client \
|
||||
|
|
@ -57,7 +56,7 @@ SHELL ["/bin/bash", "-c"]
|
|||
###########
|
||||
FROM base AS staging
|
||||
|
||||
ARG LLVM_VERSION=22
|
||||
ARG LLVM_VERSION=20
|
||||
|
||||
# Install build dependencies.
|
||||
RUN --mount=type=cache,target=/var/cache/apk,id=cache-apk,sharing=locked <<EOF
|
||||
|
|
@ -66,18 +65,15 @@ apk --update-cache add \
|
|||
ccache \
|
||||
cmake \
|
||||
g++ \
|
||||
libdwarf-dev \
|
||||
linux-headers \
|
||||
luajit-dev \
|
||||
make \
|
||||
mariadb-dev \
|
||||
ninja-build \
|
||||
ninja-is-really-ninja \
|
||||
openssl-dev \
|
||||
python3-dev \
|
||||
samurai \
|
||||
zeromq-dev \
|
||||
zlib-dev \
|
||||
zstd-dev
|
||||
zlib-dev
|
||||
EOF
|
||||
|
||||
# Install secondary dependencies as user.
|
||||
|
|
@ -142,6 +138,7 @@ COPY --chown=$UNAME:$UGROUP \
|
|||
--exclude=.git \
|
||||
--exclude=navmeshes/** \
|
||||
--exclude=ximeshes/** \
|
||||
--exclude=scripts \
|
||||
--exclude=sql \
|
||||
. /server
|
||||
|
||||
|
|
@ -154,6 +151,7 @@ ENV CCACHE_DIR=/xiadmin/.ccache
|
|||
RUN --mount=type=cache,target=/xiadmin/build,uid=$UID,gid=$GID,id=build-alpine-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
|
||||
--mount=type=cache,target=/xiadmin/.ccache,uid=$UID,gid=$GID,id=ccache-alpine-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
|
||||
--mount=type=bind,source=.git,target=/server/.git \
|
||||
--mount=type=bind,source=scripts,target=/server/scripts \
|
||||
--mount=type=bind,source=sql,target=/server/sql <<EOF
|
||||
set -eo pipefail
|
||||
cp -p /xiadmin/build/version.cpp /server/src/common/ 2> /dev/null || true
|
||||
|
|
@ -189,14 +187,13 @@ USER $UNAME
|
|||
|
||||
COPY --chown=$UNAME:$UGROUP LICENSE /server/LICENSE
|
||||
COPY --chown=$UNAME:$UGROUP res/compress.dat res/decompress.dat /server/res/
|
||||
COPY --chown=$UNAME:$UGROUP scripts /server/scripts
|
||||
COPY --chown=$UNAME:$UGROUP sql /server/sql
|
||||
COPY --chown=$UNAME:$UGROUP tools /server/tools
|
||||
COPY --chown=$UNAME:$UGROUP modules /server/modules
|
||||
COPY --chown=$UNAME:$UGROUP settings /server/settings
|
||||
|
||||
COPY --chown=$UNAME:$UGROUP --from=staging $VIRTUAL_ENV $VIRTUAL_ENV
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/data /server/data
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/scripts /server/scripts
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/xi_* /server/
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/build.log /server/build.log
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
########
|
||||
# Base #
|
||||
########
|
||||
ARG BASE_TAG=26.04
|
||||
ARG BASE_TAG=24.04
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:$BASE_TAG AS base
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
|
@ -19,7 +19,6 @@ apt-get update && apt-get install --assume-yes --no-install-recommends --quiet \
|
|||
binutils \
|
||||
ca-certificates \
|
||||
git \
|
||||
libdwarf1 \
|
||||
libzmq5 \
|
||||
lua5.1 \
|
||||
luajit \
|
||||
|
|
@ -64,8 +63,8 @@ SHELL ["/bin/bash", "-c"]
|
|||
###########
|
||||
FROM base AS staging
|
||||
|
||||
ARG GCC_VERSION=15
|
||||
ARG LLVM_VERSION=22
|
||||
ARG GCC_VERSION=14
|
||||
ARG LLVM_VERSION=20
|
||||
|
||||
# Install build dependencies.
|
||||
RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt,sharing=locked \
|
||||
|
|
@ -75,18 +74,15 @@ apt-get update && apt-get install --assume-yes --no-install-recommends --quiet \
|
|||
ccache \
|
||||
cmake \
|
||||
g++-$GCC_VERSION \
|
||||
libdwarf-dev \
|
||||
libluajit-5.1-dev \
|
||||
libmariadb-dev-compat \
|
||||
libssl-dev \
|
||||
libzmq3-dev \
|
||||
make \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3-dev \
|
||||
python3-venv \
|
||||
zlib1g-dev \
|
||||
libzstd-dev
|
||||
zlib1g-dev
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$GCC_VERSION 100
|
||||
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-$GCC_VERSION 100
|
||||
EOF
|
||||
|
|
@ -154,6 +150,7 @@ COPY --chown=$UNAME:$UGROUP \
|
|||
--exclude=.git \
|
||||
--exclude=navmeshes/** \
|
||||
--exclude=ximeshes/** \
|
||||
--exclude=scripts \
|
||||
--exclude=sql \
|
||||
. /server
|
||||
|
||||
|
|
@ -166,6 +163,7 @@ ENV CCACHE_DIR=/xiadmin/.ccache
|
|||
RUN --mount=type=cache,target=/xiadmin/build,uid=$UID,gid=$GID,id=build-ubuntu-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
|
||||
--mount=type=cache,target=/xiadmin/.ccache,uid=$UID,gid=$GID,id=ccache-ubuntu-$COMPILER-$CMAKE_BUILD_TYPE-tracy$TRACY_ENABLE-pch$PCH_ENABLE \
|
||||
--mount=type=bind,source=.git,target=/server/.git \
|
||||
--mount=type=bind,source=scripts,target=/server/scripts \
|
||||
--mount=type=bind,source=sql,target=/server/sql <<EOF
|
||||
set -eo pipefail
|
||||
cp -p /xiadmin/build/version.cpp /server/src/common/ 2> /dev/null || true
|
||||
|
|
@ -201,14 +199,13 @@ USER $UNAME
|
|||
|
||||
COPY --chown=$UNAME:$UGROUP LICENSE /server/LICENSE
|
||||
COPY --chown=$UNAME:$UGROUP res/compress.dat res/decompress.dat /server/res/
|
||||
COPY --chown=$UNAME:$UGROUP scripts /server/scripts
|
||||
COPY --chown=$UNAME:$UGROUP sql /server/sql
|
||||
COPY --chown=$UNAME:$UGROUP tools /server/tools
|
||||
COPY --chown=$UNAME:$UGROUP modules /server/modules
|
||||
COPY --chown=$UNAME:$UGROUP settings /server/settings
|
||||
|
||||
COPY --chown=$UNAME:$UGROUP --from=staging $VIRTUAL_ENV $VIRTUAL_ENV
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/data /server/data
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/scripts /server/scripts
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/xi_* /server/
|
||||
COPY --chown=$UNAME:$UGROUP --from=build /server/build.log /server/build.log
|
||||
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@
|
|||
ALL_WSDMG_FIRST_HIT = 841, // Generic (all Weaponskills) damage, first hit only.
|
||||
AUTO_DECISION_DELAY = 842, // Reduces the Automaton's global decision delay
|
||||
AUTO_SHIELD_BASH_DELAY = 843, // Reduces the Automaton's global shield bash delay
|
||||
AUTO_MAGIC_COOLDOWN = 844, // Adjusts the Automaton's global magic cooldown. (negative value reduces cooldown, positive value increases cooldown)
|
||||
AUTO_MAGIC_DELAY = 844, // Reduces the Automaton's global magic delay
|
||||
AUTO_HEALING_DELAY = 845, // Reduces the Automaton's global healing delay
|
||||
AUTO_HEALING_THRESHOLD = 846, // Increases the healing trigger threshold
|
||||
BURDEN_DECAY = 847, // Increases amount of burden removed per tick
|
||||
|
|
@ -653,8 +653,8 @@
|
|||
// SPARE ID 936
|
||||
|
||||
FOOD_DURATION = 937, // Percentage to increase food duration
|
||||
// SPARE ID 938
|
||||
AUTO_STEAM_JACKET_REDUCTION = 939, // Percent damage reduction from Steam Jacket
|
||||
AUTO_STEAM_JACKET = 938, // Causes the Automaton to mitigate damage from successive attacks of the same type
|
||||
AUTO_STEAM_JACKET_REDUCTION = 939, // Amount of damage reduced with Steam Jacket
|
||||
AUTO_SCHURZEN = 940, // Prevents fatal damage leaving the automaton at 1HP and consumes an Earth manuever
|
||||
AUTO_EQUALIZER = 941, // Reduces damage received according to damage taken
|
||||
AUTO_PERFORMANCE_BOOST = 942, // Increases the performance of other attachments by a percentage
|
||||
|
|
@ -770,3 +770,4 @@
|
|||
// For example, +10% damage to Chant du Cygne would be ID 570 + 225 (795)
|
||||
|
||||
// SPARE = 1077,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# add_subdirectory(lua) # Handled globally
|
||||
# add_subdirectory(mariadb) # Handled globally
|
||||
# add_subdirectory(mariadbcpp) # Handled globally
|
||||
# add_subdirectory(zmq) # Handled globally
|
||||
# add_subdirectory(openssl) # Handled globally
|
||||
add_subdirectory(concurrentqueue)
|
||||
add_subdirectory(SPSCQueue)
|
||||
add_subdirectory(sol)
|
||||
|
||||
# CPM Modules
|
||||
|
|
@ -42,55 +42,31 @@ if(TRACY_ENABLE)
|
|||
tar xvf "${CMAKE_SOURCE_DIR}/tracy.tar.gz"
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/
|
||||
)
|
||||
else() # UNIX (Linux / macOS)
|
||||
include(ExternalProject)
|
||||
else() # UNIX
|
||||
# TODO: Auto-build Tracy and capture executables on Linux
|
||||
# sudo apt-get -y install libglfw3-dev libdbus-1-dev libcapstone-dev libtbb-dev libdebuginfod-dev libfreetype-dev
|
||||
|
||||
# target name:source subdirectory
|
||||
set(TRACY_TOOLS
|
||||
"tracy-capture:capture"
|
||||
"tracy-csvexport:csvexport"
|
||||
)
|
||||
# execute_process(COMMAND "make"
|
||||
# WORKING_DIRECTORY ${tracy_SOURCE_DIR}/profiler/build/unix
|
||||
# )
|
||||
|
||||
foreach(_tracy_tool ${TRACY_TOOLS})
|
||||
string(REPLACE ":" ";" _tracy_tool "${_tracy_tool}")
|
||||
list(GET _tracy_tool 0 _tracy_tool_name)
|
||||
list(GET _tracy_tool 1 _tracy_tool_dir)
|
||||
|
||||
message(STATUS "Configuring Tracy tool: ${_tracy_tool_name}")
|
||||
|
||||
set(_tracy_tool_bindir ${CMAKE_BINARY_DIR}/tracy-tools/${_tracy_tool_name})
|
||||
|
||||
ExternalProject_Add(${_tracy_tool_name}
|
||||
SOURCE_DIR ${TracyClient_SOURCE_DIR}/${_tracy_tool_dir}
|
||||
BINARY_DIR ${_tracy_tool_bindir}
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}
|
||||
-DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}
|
||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${_tracy_tool_bindir}
|
||||
BUILD_ALWAYS TRUE
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${_tracy_tool_bindir}/${_tracy_tool_name}
|
||||
${CMAKE_SOURCE_DIR}/${_tracy_tool_name}
|
||||
)
|
||||
endforeach()
|
||||
# execute_process(COMMAND "make"
|
||||
# WORKING_DIRECTORY ${tracy_SOURCE_DIR}/capture/build/unix
|
||||
# )
|
||||
endif()
|
||||
endif(TRACY_ENABLE)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME fmt
|
||||
GITHUB_REPOSITORY fmtlib/fmt
|
||||
GIT_TAG 12.2.0
|
||||
GIT_TAG 11.2.0
|
||||
SYSTEM ON
|
||||
) # defines: fmt::fmt
|
||||
|
||||
CPMAddPackage(
|
||||
NAME spdlog
|
||||
GITHUB_REPOSITORY gabime/spdlog
|
||||
GIT_TAG v1.17.0
|
||||
GIT_TAG v1.15.3
|
||||
SYSTEM ON
|
||||
OPTIONS
|
||||
"SPDLOG_ENABLE_PCH ON"
|
||||
|
|
@ -100,9 +76,11 @@ CPMAddPackage(
|
|||
CPMAddPackage(
|
||||
NAME recastnavigation
|
||||
GITHUB_REPOSITORY recastnavigation/recastnavigation
|
||||
GIT_TAG 1078bfe346d9bb560faa748c8fde2e7aae73a3ab
|
||||
GIT_TAG bd98d84c274ee06842bf51a4088ca82ac71f8c2d
|
||||
SYSTEM ON
|
||||
OPTIONS
|
||||
# TODO: Remove this once recast is updated to use CMake 3.5+, it's currently set to what we use in the root CMakeLists.txt
|
||||
"CMAKE_POLICY_VERSION_MINIMUM 3.20"
|
||||
"RECASTNAVIGATION_DEMO OFF"
|
||||
"RECASTNAVIGATION_TESTS OFF"
|
||||
"RECASTNAVIGATION_EXAMPLES OFF"
|
||||
|
|
@ -132,7 +110,7 @@ endif()
|
|||
CPMAddPackage(
|
||||
NAME rapidyaml
|
||||
GITHUB_REPOSITORY biojppm/rapidyaml
|
||||
GIT_TAG v0.15.2
|
||||
GIT_TAG v0.12.0
|
||||
SYSTEM ON
|
||||
OPTIONS
|
||||
"RYML_BUILD_TOOLS OFF"
|
||||
|
|
@ -149,8 +127,8 @@ CPMAddPackage(
|
|||
|
||||
CPMAddPackage(
|
||||
NAME efsw
|
||||
GITHUB_REPOSITORY SpartanJ/efsw
|
||||
GIT_TAG 22f17a0bcdf3a4edf61f8b14328391463389e548 # master
|
||||
GITHUB_REPOSITORY zach2good/efsw
|
||||
GIT_TAG c37c7e0fc6bbd63659edeba458273c35a51513da # master
|
||||
SYSTEM ON
|
||||
OPTIONS
|
||||
"VERBOSE OFF"
|
||||
|
|
@ -171,7 +149,7 @@ CPMAddPackage(
|
|||
CPMAddPackage(
|
||||
NAME cpp-httplib
|
||||
GITHUB_REPOSITORY yhirose/cpp-httplib
|
||||
GIT_TAG v0.49.0
|
||||
GIT_TAG v0.18.3
|
||||
SYSTEM ON
|
||||
OPTIONS
|
||||
"HTTPLIB_REQUIRE_ZLIB OFF"
|
||||
|
|
@ -181,7 +159,7 @@ CPMAddPackage(
|
|||
CPMAddPackage(
|
||||
NAME json
|
||||
GITHUB_REPOSITORY nlohmann/json
|
||||
GIT_TAG v3.12.0
|
||||
GIT_TAG 9f60e855576bb1e95f39ab23b3821982cccb0bab
|
||||
SYSTEM ON
|
||||
) # defines: nlohmann_json::nlohmann_json
|
||||
|
||||
|
|
@ -197,9 +175,9 @@ endif()
|
|||
|
||||
CPMAddPackage(
|
||||
NAME asio
|
||||
VERSION 1.38.0
|
||||
VERSION 1.36.0
|
||||
GITHUB_REPOSITORY chriskohlhoff/asio
|
||||
GIT_TAG asio-1-38-0 # asio uses non-standard version tag, we must specify GIT_TAG
|
||||
GIT_TAG asio-1-36-0 # asio uses non-standard version tag, we must specify GIT_TAG
|
||||
) #defines asio
|
||||
|
||||
# ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows:
|
||||
|
|
@ -209,7 +187,7 @@ CPMAddPackage(
|
|||
if(asio_ADDED)
|
||||
add_library(asio INTERFACE)
|
||||
|
||||
target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/include)
|
||||
target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/asio/include)
|
||||
|
||||
target_compile_definitions(asio INTERFACE ASIO_STANDALONE ASIO_NO_DEPRECATED)
|
||||
|
||||
|
|
@ -281,7 +259,7 @@ CPMAddPackage(
|
|||
CPMAddPackage(
|
||||
NAME magic_enum
|
||||
GITHUB_REPOSITORY Neargye/magic_enum
|
||||
GIT_TAG v0.9.8
|
||||
GIT_TAG 1a1824df7ac798177a521eed952720681b0bf482
|
||||
SYSTEM ON
|
||||
) # defines: magic_enum
|
||||
|
||||
|
|
@ -292,56 +270,12 @@ CPMAddPackage(
|
|||
SYSTEM ON
|
||||
) # defines: termcolor::termcolor
|
||||
|
||||
CPMAddPackage(
|
||||
NAME unordered_dense
|
||||
GITHUB_REPOSITORY martinus/unordered_dense
|
||||
GIT_TAG v4.8.1
|
||||
SYSTEM ON
|
||||
) # defines: unordered_dense::unordered_dense (aliased to FlatHashMap, see src/common/flat_hash_map.h)
|
||||
|
||||
# TODO: std::move_only_function lands in C++23, but libc++ (macOS) has not implemented
|
||||
# : it yet. Remove this once all compilers for all platforms implement.
|
||||
CPMAddPackage(
|
||||
NAME function2
|
||||
GITHUB_REPOSITORY Naios/function2
|
||||
GIT_TAG 4.2.4
|
||||
SYSTEM ON
|
||||
) # defines: function2 (aliased to Fn, see src/common/types/fn.h)
|
||||
|
||||
# How cpptrace turns a crash address into function + file:line, per platform:
|
||||
set(CPPTRACE_SYMBOL_OPTIONS "")
|
||||
if(APPLE)
|
||||
# macOS binaries carry a "debug map" pointing at the .o files rather than embedded DWARF;
|
||||
# atos resolves against the staged .dSYM (see set_target_output_directory) and is fast.
|
||||
list(APPEND CPPTRACE_SYMBOL_OPTIONS
|
||||
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF OFF"
|
||||
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE ON"
|
||||
)
|
||||
elseif(UNIX)
|
||||
# Linux: resolve in-process with libdwarf.
|
||||
list(APPEND CPPTRACE_SYMBOL_OPTIONS
|
||||
"CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE OFF"
|
||||
"CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF ON"
|
||||
"CPPTRACE_USE_EXTERNAL_LIBDWARF ON"
|
||||
"CPPTRACE_FIND_LIBDWARF_WITH_PKGCONFIG ON"
|
||||
)
|
||||
endif()
|
||||
|
||||
CPMAddPackage(
|
||||
NAME cpptrace
|
||||
GITHUB_REPOSITORY jeremy-rifkin/cpptrace
|
||||
GIT_TAG v1.0.4
|
||||
SYSTEM ON
|
||||
OPTIONS
|
||||
${CPPTRACE_SYMBOL_OPTIONS}
|
||||
) # defines: cpptrace::cpptrace
|
||||
|
||||
set(SHARED_EXTERNAL_LIBS
|
||||
fmt::fmt
|
||||
spdlog
|
||||
concurrentqueue
|
||||
spscqueue
|
||||
mariadbclient
|
||||
mariadbcpp
|
||||
sol2_single
|
||||
argparse
|
||||
efsw
|
||||
|
|
@ -351,16 +285,25 @@ set(SHARED_EXTERNAL_LIBS
|
|||
alpaca
|
||||
magic_enum
|
||||
utf8cpp
|
||||
unordered_dense::unordered_dense
|
||||
function2
|
||||
cpptrace::cpptrace
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
if(WIN32)
|
||||
# add wepoll for epoll support on windows
|
||||
add_subdirectory(wepoll)
|
||||
|
||||
list(APPEND SHARED_EXTERNAL_LIBS
|
||||
wepoll
|
||||
)
|
||||
|
||||
# backwards needs these to add to linker
|
||||
elseif(APPLE)
|
||||
# MacOS has bfd built in clang
|
||||
list(APPEND SHARED_EXTERNAL_LIBS
|
||||
dl
|
||||
)
|
||||
elseif(UNIX)
|
||||
# Linux needs bfd as it's not native like MacOS
|
||||
# bfd may link zstd
|
||||
list(APPEND SHARED_EXTERNAL_LIBS
|
||||
bfd
|
||||
dl
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
add_library(spscqueue INTERFACE)
|
||||
target_sources(spscqueue INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/rigtorp/SPSCQueue.h)
|
||||
target_include_directories(spscqueue SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <memory> // std::allocator
|
||||
#include <new> // std::hardware_destructive_interference_size
|
||||
#include <stdexcept>
|
||||
#include <type_traits> // std::enable_if, std::is_*_constructible
|
||||
|
||||
#ifdef __has_cpp_attribute
|
||||
#if __has_cpp_attribute(nodiscard)
|
||||
#define RIGTORP_NODISCARD [[nodiscard]]
|
||||
#endif
|
||||
#endif
|
||||
#ifndef RIGTORP_NODISCARD
|
||||
#define RIGTORP_NODISCARD
|
||||
#endif
|
||||
|
||||
namespace rigtorp {
|
||||
|
||||
template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
|
||||
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_lib_void_t)
|
||||
template <typename Alloc2, typename = void>
|
||||
struct has_allocate_at_least : std::false_type {};
|
||||
|
||||
template <typename Alloc2>
|
||||
struct has_allocate_at_least<
|
||||
Alloc2, std::void_t<typename Alloc2::value_type,
|
||||
decltype(std::declval<Alloc2 &>().allocate_at_least(
|
||||
size_t{}))>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit SPSCQueue(const size_t capacity,
|
||||
const Allocator &allocator = Allocator())
|
||||
: capacity_(capacity), allocator_(allocator) {
|
||||
// The queue needs at least one element
|
||||
if (capacity_ < 1) {
|
||||
capacity_ = 1;
|
||||
}
|
||||
capacity_++; // Needs one slack element
|
||||
// Prevent overflowing size_t
|
||||
if (capacity_ > SIZE_MAX - 2 * kPadding) {
|
||||
capacity_ = SIZE_MAX - 2 * kPadding;
|
||||
}
|
||||
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_lib_void_t)
|
||||
if constexpr (has_allocate_at_least<Allocator>::value) {
|
||||
auto res = allocator_.allocate_at_least(capacity_ + 2 * kPadding);
|
||||
slots_ = res.ptr;
|
||||
capacity_ = res.count - 2 * kPadding;
|
||||
} else {
|
||||
slots_ = std::allocator_traits<Allocator>::allocate(
|
||||
allocator_, capacity_ + 2 * kPadding);
|
||||
}
|
||||
#else
|
||||
slots_ = std::allocator_traits<Allocator>::allocate(
|
||||
allocator_, capacity_ + 2 * kPadding);
|
||||
#endif
|
||||
|
||||
static_assert(alignof(SPSCQueue<T>) == kCacheLineSize, "");
|
||||
static_assert(sizeof(SPSCQueue<T>) >= 3 * kCacheLineSize, "");
|
||||
assert(reinterpret_cast<char *>(&readIdx_) -
|
||||
reinterpret_cast<char *>(&writeIdx_) >=
|
||||
static_cast<std::ptrdiff_t>(kCacheLineSize));
|
||||
}
|
||||
|
||||
~SPSCQueue() {
|
||||
while (front()) {
|
||||
pop();
|
||||
}
|
||||
std::allocator_traits<Allocator>::deallocate(allocator_, slots_,
|
||||
capacity_ + 2 * kPadding);
|
||||
}
|
||||
|
||||
// non-copyable and non-movable
|
||||
SPSCQueue(const SPSCQueue &) = delete;
|
||||
SPSCQueue &operator=(const SPSCQueue &) = delete;
|
||||
|
||||
template <typename... Args>
|
||||
void emplace(Args &&...args) noexcept(
|
||||
std::is_nothrow_constructible<T, Args &&...>::value) {
|
||||
static_assert(std::is_constructible<T, Args &&...>::value,
|
||||
"T must be constructible with Args&&...");
|
||||
auto const writeIdx = writeIdx_.load(std::memory_order_relaxed);
|
||||
auto nextWriteIdx = writeIdx + 1;
|
||||
if (nextWriteIdx == capacity_) {
|
||||
nextWriteIdx = 0;
|
||||
}
|
||||
while (nextWriteIdx == readIdxCache_) {
|
||||
readIdxCache_ = readIdx_.load(std::memory_order_acquire);
|
||||
}
|
||||
new (&slots_[writeIdx + kPadding]) T(std::forward<Args>(args)...);
|
||||
writeIdx_.store(nextWriteIdx, std::memory_order_release);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
RIGTORP_NODISCARD bool try_emplace(Args &&...args) noexcept(
|
||||
std::is_nothrow_constructible<T, Args &&...>::value) {
|
||||
static_assert(std::is_constructible<T, Args &&...>::value,
|
||||
"T must be constructible with Args&&...");
|
||||
auto const writeIdx = writeIdx_.load(std::memory_order_relaxed);
|
||||
auto nextWriteIdx = writeIdx + 1;
|
||||
if (nextWriteIdx == capacity_) {
|
||||
nextWriteIdx = 0;
|
||||
}
|
||||
if (nextWriteIdx == readIdxCache_) {
|
||||
readIdxCache_ = readIdx_.load(std::memory_order_acquire);
|
||||
if (nextWriteIdx == readIdxCache_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
new (&slots_[writeIdx + kPadding]) T(std::forward<Args>(args)...);
|
||||
writeIdx_.store(nextWriteIdx, std::memory_order_release);
|
||||
return true;
|
||||
}
|
||||
|
||||
void push(const T &v) noexcept(std::is_nothrow_copy_constructible<T>::value) {
|
||||
static_assert(std::is_copy_constructible<T>::value,
|
||||
"T must be copy constructible");
|
||||
emplace(v);
|
||||
}
|
||||
|
||||
template <typename P, typename = typename std::enable_if<
|
||||
std::is_constructible<T, P &&>::value>::type>
|
||||
void push(P &&v) noexcept(std::is_nothrow_constructible<T, P &&>::value) {
|
||||
emplace(std::forward<P>(v));
|
||||
}
|
||||
|
||||
RIGTORP_NODISCARD bool
|
||||
try_push(const T &v) noexcept(std::is_nothrow_copy_constructible<T>::value) {
|
||||
static_assert(std::is_copy_constructible<T>::value,
|
||||
"T must be copy constructible");
|
||||
return try_emplace(v);
|
||||
}
|
||||
|
||||
template <typename P, typename = typename std::enable_if<
|
||||
std::is_constructible<T, P &&>::value>::type>
|
||||
RIGTORP_NODISCARD bool
|
||||
try_push(P &&v) noexcept(std::is_nothrow_constructible<T, P &&>::value) {
|
||||
return try_emplace(std::forward<P>(v));
|
||||
}
|
||||
|
||||
RIGTORP_NODISCARD T *front() noexcept {
|
||||
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
|
||||
if (readIdx == writeIdxCache_) {
|
||||
writeIdxCache_ = writeIdx_.load(std::memory_order_acquire);
|
||||
if (writeIdxCache_ == readIdx) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return &slots_[readIdx + kPadding];
|
||||
}
|
||||
|
||||
void pop() noexcept {
|
||||
static_assert(std::is_nothrow_destructible<T>::value,
|
||||
"T must be nothrow destructible");
|
||||
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
|
||||
assert(writeIdx_.load(std::memory_order_acquire) != readIdx &&
|
||||
"Can only call pop() after front() has returned a non-nullptr");
|
||||
slots_[readIdx + kPadding].~T();
|
||||
auto nextReadIdx = readIdx + 1;
|
||||
if (nextReadIdx == capacity_) {
|
||||
nextReadIdx = 0;
|
||||
}
|
||||
readIdx_.store(nextReadIdx, std::memory_order_release);
|
||||
}
|
||||
|
||||
RIGTORP_NODISCARD size_t size() const noexcept {
|
||||
std::ptrdiff_t diff = writeIdx_.load(std::memory_order_acquire) -
|
||||
readIdx_.load(std::memory_order_acquire);
|
||||
if (diff < 0) {
|
||||
diff += capacity_;
|
||||
}
|
||||
return static_cast<size_t>(diff);
|
||||
}
|
||||
|
||||
RIGTORP_NODISCARD bool empty() const noexcept {
|
||||
return writeIdx_.load(std::memory_order_acquire) ==
|
||||
readIdx_.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
RIGTORP_NODISCARD size_t capacity() const noexcept { return capacity_ - 1; }
|
||||
|
||||
private:
|
||||
#ifdef __cpp_lib_hardware_interference_size
|
||||
static constexpr size_t kCacheLineSize =
|
||||
std::hardware_destructive_interference_size;
|
||||
#else
|
||||
static constexpr size_t kCacheLineSize = 64;
|
||||
#endif
|
||||
|
||||
// Padding to avoid false sharing between slots_ and adjacent allocations
|
||||
static constexpr size_t kPadding = (kCacheLineSize - 1) / sizeof(T) + 1;
|
||||
|
||||
private:
|
||||
size_t capacity_;
|
||||
T *slots_;
|
||||
#if defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address)
|
||||
Allocator allocator_ [[no_unique_address]];
|
||||
#else
|
||||
Allocator allocator_;
|
||||
#endif
|
||||
|
||||
// Align to cache line size in order to avoid false sharing
|
||||
// readIdxCache_ and writeIdxCache_ is used to reduce the amount of cache
|
||||
// coherency traffic
|
||||
alignas(kCacheLineSize) std::atomic<size_t> writeIdx_ = {0};
|
||||
alignas(kCacheLineSize) size_t readIdxCache_ = 0;
|
||||
alignas(kCacheLineSize) std::atomic<size_t> readIdx_ = {0};
|
||||
alignas(kCacheLineSize) size_t writeIdxCache_ = 0;
|
||||
};
|
||||
} // namespace rigtorp
|
||||
21
ext/backward/LICENSE.txt
Normal file
21
ext/backward/LICENSE.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
42
ext/backward/backward.cpp
Normal file
42
ext/backward/backward.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Pick your poison.
|
||||
//
|
||||
// On GNU/Linux, you have few choices to get the most out of your stack trace.
|
||||
//
|
||||
// By default you get:
|
||||
// - object filename
|
||||
// - function name
|
||||
//
|
||||
// In order to add:
|
||||
// - source filename
|
||||
// - line and column numbers
|
||||
// - source code snippet (assuming the file is accessible)
|
||||
|
||||
// Install one of the following libraries then uncomment one of the macro (or
|
||||
// better, add the detection of the lib and the macro definition in your build
|
||||
// system)
|
||||
|
||||
// - apt-get install libdw-dev ...
|
||||
// - g++/clang++ -ldw ...
|
||||
// #define BACKWARD_HAS_DW 1
|
||||
|
||||
// - apt-get install binutils-dev ...
|
||||
// - g++/clang++ -lbfd ...
|
||||
// #define BACKWARD_HAS_BFD 1
|
||||
|
||||
// - apt-get install libdwarf-dev ...
|
||||
// - g++/clang++ -ldwarf ...
|
||||
// #define BACKWARD_HAS_DWARF 1
|
||||
|
||||
// Regardless of the library you choose to read the debug information,
|
||||
// for potentially more detailed stack traces you can use libunwind
|
||||
// - apt-get install libunwind-dev
|
||||
// - g++/clang++ -lunwind
|
||||
// #define BACKWARD_HAS_LIBUNWIND 1
|
||||
|
||||
#include "backward.hpp"
|
||||
|
||||
namespace backward {
|
||||
|
||||
backward::SignalHandling sh;
|
||||
|
||||
} // namespace backward
|
||||
4514
ext/backward/backward.hpp
Normal file
4514
ext/backward/backward.hpp
Normal file
File diff suppressed because it is too large
Load diff
9
ext/wepoll/CMakeLists.txt
Normal file
9
ext/wepoll/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
set(SOURCES
|
||||
wepoll.c
|
||||
wepoll.h
|
||||
)
|
||||
|
||||
add_library(wepoll STATIC ${SOURCES})
|
||||
target_include_directories(wepoll SYSTEM PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
28
ext/wepoll/LICENSE
Normal file
28
ext/wepoll/LICENSE
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
wepoll - epoll for Windows
|
||||
https://github.com/piscisaureus/wepoll
|
||||
|
||||
Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
202
ext/wepoll/README.md
Normal file
202
ext/wepoll/README.md
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
# wepoll - epoll for windows
|
||||
|
||||
[![][ci status badge]][ci status link]
|
||||
|
||||
This library implements the [epoll][man epoll] API for Windows
|
||||
applications. It is fast and scalable, and it closely resembles the API
|
||||
and behavior of Linux' epoll.
|
||||
|
||||
## Rationale
|
||||
|
||||
Unlike Linux, OS X, and many other operating systems, Windows doesn't
|
||||
have a good API for receiving socket state notifications. It only
|
||||
supports the `select` and `WSAPoll` APIs, but they
|
||||
[don't scale][select scale] and suffer from
|
||||
[other issues][wsapoll broken].
|
||||
|
||||
Using I/O completion ports isn't always practical when software is
|
||||
designed to be cross-platform. Wepoll offers an alternative that is
|
||||
much closer to a drop-in replacement for software that was designed
|
||||
to run on Linux.
|
||||
|
||||
## Features
|
||||
|
||||
* Can poll 100000s of sockets efficiently.
|
||||
* Fully thread-safe.
|
||||
* Multiple threads can poll the same epoll port.
|
||||
* Sockets can be added to multiple epoll sets.
|
||||
* All epoll events (`EPOLLIN`, `EPOLLOUT`, `EPOLLPRI`, `EPOLLRDHUP`)
|
||||
are supported.
|
||||
* Level-triggered and one-shot (`EPOLLONESTHOT`) modes are supported
|
||||
* Trivial to embed: you need [only two files][dist].
|
||||
|
||||
## Limitations
|
||||
|
||||
* Only works with sockets.
|
||||
* Edge-triggered (`EPOLLET`) mode isn't supported.
|
||||
|
||||
## How to use
|
||||
|
||||
The library is [distributed][dist] as a single source file
|
||||
([wepoll.c][wepoll.c]) and a single header file ([wepoll.h][wepoll.h]).<br>
|
||||
Compile the .c file as part of your project, and include the header wherever
|
||||
needed.
|
||||
|
||||
## Compatibility
|
||||
|
||||
* Requires Windows Vista or higher.
|
||||
* Can be compiled with recent versions of MSVC, Clang, and GCC.
|
||||
|
||||
## API
|
||||
|
||||
### General remarks
|
||||
|
||||
* The epoll port is a `HANDLE`, not a file descriptor.
|
||||
* All functions set both `errno` and `GetLastError()` on failure.
|
||||
* For more extensive documentation, see the [epoll(7) man page][man epoll],
|
||||
and the per-function man pages that are linked below.
|
||||
|
||||
### epoll_create/epoll_create1
|
||||
|
||||
```c
|
||||
HANDLE epoll_create(int size);
|
||||
HANDLE epoll_create1(int flags);
|
||||
```
|
||||
|
||||
* Create a new epoll instance (port).
|
||||
* `size` is ignored but most be greater than zero.
|
||||
* `flags` must be zero as there are no supported flags.
|
||||
* Returns `NULL` on failure.
|
||||
* [Linux man page][man epoll_create]
|
||||
|
||||
### epoll_close
|
||||
|
||||
```c
|
||||
int epoll_close(HANDLE ephnd);
|
||||
```
|
||||
|
||||
* Close an epoll port.
|
||||
* Do not attempt to close the epoll port with `close()`,
|
||||
`CloseHandle()` or `closesocket()`.
|
||||
|
||||
### epoll_ctl
|
||||
|
||||
```c
|
||||
int epoll_ctl(HANDLE ephnd,
|
||||
int op,
|
||||
SOCKET sock,
|
||||
struct epoll_event* event);
|
||||
```
|
||||
|
||||
* Control which socket events are monitored by an epoll port.
|
||||
* `ephnd` must be a HANDLE created by
|
||||
[`epoll_create()`](#epoll_createepoll_create1) or
|
||||
[`epoll_create1()`](#epoll_createepoll_create1).
|
||||
* `op` must be one of `EPOLL_CTL_ADD`, `EPOLL_CTL_MOD`, `EPOLL_CTL_DEL`.
|
||||
* `sock` must be a valid socket created by [`socket()`][msdn socket],
|
||||
[`WSASocket()`][msdn wsasocket], or [`accept()`][msdn accept].
|
||||
* `event` should be a pointer to a [`struct epoll_event`](#struct-epoll_event).<br>
|
||||
If `op` is `EPOLL_CTL_DEL` then the `event` parameter is ignored, and it
|
||||
may be `NULL`.
|
||||
* Returns 0 on success, -1 on failure.
|
||||
* It is recommended to always explicitly remove a socket from its epoll
|
||||
set using `EPOLL_CTL_DEL` *before* closing it.<br>
|
||||
As on Linux, closed sockets are automatically removed from the epoll set, but
|
||||
wepoll may not be able to detect that a socket was closed until the next call
|
||||
to [`epoll_wait()`](#epoll_wait).
|
||||
* [Linux man page][man epoll_ctl]
|
||||
|
||||
### epoll_wait
|
||||
|
||||
```c
|
||||
int epoll_wait(HANDLE ephnd,
|
||||
struct epoll_event* events,
|
||||
int maxevents,
|
||||
int timeout);
|
||||
```
|
||||
|
||||
* Receive socket events from an epoll port.
|
||||
* `events` should point to a caller-allocated array of
|
||||
[`epoll_event`](#struct-epoll_event) structs, which will receive the
|
||||
reported events.
|
||||
* `maxevents` is the maximum number of events that will be written to the
|
||||
`events` array, and must be greater than zero.
|
||||
* `timeout` specifies whether to block when no events are immediately available.
|
||||
- `<0` block indefinitely
|
||||
- `0` report any events that are already waiting, but don't block
|
||||
- `≥1` block for at most N milliseconds
|
||||
* Return value:
|
||||
- `-1` an error occurred
|
||||
- `0` timed out without any events to report
|
||||
- `≥1` the number of events stored in the `events` buffer
|
||||
* [Linux man page][man epoll_wait]
|
||||
|
||||
### struct epoll_event
|
||||
|
||||
```c
|
||||
typedef union epoll_data {
|
||||
void* ptr;
|
||||
int fd;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
SOCKET sock; /* Windows specific */
|
||||
HANDLE hnd; /* Windows specific */
|
||||
} epoll_data_t;
|
||||
```
|
||||
|
||||
```c
|
||||
struct epoll_event {
|
||||
uint32_t events; /* Epoll events and flags */
|
||||
epoll_data_t data; /* User data variable */
|
||||
};
|
||||
```
|
||||
|
||||
* The `events` field is a bit mask containing the events being
|
||||
monitored/reported, and optional flags.<br>
|
||||
Flags are accepted by [`epoll_ctl()`](#epoll_ctl), but they are not reported
|
||||
back by [`epoll_wait()`](#epoll_wait).
|
||||
* The `data` field can be used to associate application-specific information
|
||||
with a socket; its value will be returned unmodified by
|
||||
[`epoll_wait()`](#epoll_wait).
|
||||
* [Linux man page][man epoll_ctl]
|
||||
|
||||
| Event | Description |
|
||||
|---------------|----------------------------------------------------------------------|
|
||||
| `EPOLLIN` | incoming data available, or incoming connection ready to be accepted |
|
||||
| `EPOLLOUT` | ready to send data, or outgoing connection successfully established |
|
||||
| `EPOLLRDHUP` | remote peer initiated graceful socket shutdown |
|
||||
| `EPOLLPRI` | out-of-band data available for reading |
|
||||
| `EPOLLERR` | socket error<sup>1</sup> |
|
||||
| `EPOLLHUP` | socket hang-up<sup>1</sup> |
|
||||
| `EPOLLRDNORM` | same as `EPOLLIN` |
|
||||
| `EPOLLRDBAND` | same as `EPOLLPRI` |
|
||||
| `EPOLLWRNORM` | same as `EPOLLOUT` |
|
||||
| `EPOLLWRBAND` | same as `EPOLLOUT` |
|
||||
| `EPOLLMSG` | never reported |
|
||||
|
||||
| Flag | Description |
|
||||
|------------------|---------------------------|
|
||||
| `EPOLLONESHOT` | report event(s) only once |
|
||||
| `EPOLLET` | not supported by wepoll |
|
||||
| `EPOLLEXCLUSIVE` | not supported by wepoll |
|
||||
| `EPOLLWAKEUP` | not supported by wepoll |
|
||||
|
||||
<sup>1</sup>: the `EPOLLERR` and `EPOLLHUP` events may always be reported by
|
||||
[`epoll_wait()`](#epoll_wait), regardless of the event mask that was passed to
|
||||
[`epoll_ctl()`](#epoll_ctl).
|
||||
|
||||
|
||||
[ci status badge]: https://ci.appveyor.com/api/projects/status/github/piscisaureus/wepoll?branch=master&svg=true
|
||||
[ci status link]: https://ci.appveyor.com/project/piscisaureus/wepoll/branch/master
|
||||
[dist]: https://github.com/piscisaureus/wepoll/tree/dist
|
||||
[man epoll]: http://man7.org/linux/man-pages/man7/epoll.7.html
|
||||
[man epoll_create]: http://man7.org/linux/man-pages/man2/epoll_create.2.html
|
||||
[man epoll_ctl]: http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
|
||||
[man epoll_wait]: http://man7.org/linux/man-pages/man2/epoll_wait.2.html
|
||||
[msdn accept]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx
|
||||
[msdn socket]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx
|
||||
[msdn wsasocket]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx
|
||||
[select scale]: https://daniel.haxx.se/docs/poll-vs-select.html
|
||||
[wsapoll broken]: https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
|
||||
[wepoll.c]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.c
|
||||
[wepoll.h]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.h
|
||||
2253
ext/wepoll/wepoll.c
Normal file
2253
ext/wepoll/wepoll.c
Normal file
File diff suppressed because it is too large
Load diff
113
ext/wepoll/wepoll.h
Normal file
113
ext/wepoll/wepoll.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* wepoll - epoll for Windows
|
||||
* https://github.com/piscisaureus/wepoll
|
||||
*
|
||||
* Copyright 2012-2020, Bert Belder <bertbelder@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef WEPOLL_H_
|
||||
#define WEPOLL_H_
|
||||
|
||||
#ifndef WEPOLL_EXPORT
|
||||
#define WEPOLL_EXPORT
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum EPOLL_EVENTS {
|
||||
EPOLLIN = (int) (1U << 0),
|
||||
EPOLLPRI = (int) (1U << 1),
|
||||
EPOLLOUT = (int) (1U << 2),
|
||||
EPOLLERR = (int) (1U << 3),
|
||||
EPOLLHUP = (int) (1U << 4),
|
||||
EPOLLRDNORM = (int) (1U << 6),
|
||||
EPOLLRDBAND = (int) (1U << 7),
|
||||
EPOLLWRNORM = (int) (1U << 8),
|
||||
EPOLLWRBAND = (int) (1U << 9),
|
||||
EPOLLMSG = (int) (1U << 10), /* Never reported. */
|
||||
EPOLLRDHUP = (int) (1U << 13),
|
||||
EPOLLONESHOT = (int) (1U << 31)
|
||||
};
|
||||
|
||||
#define EPOLLIN (1U << 0)
|
||||
#define EPOLLPRI (1U << 1)
|
||||
#define EPOLLOUT (1U << 2)
|
||||
#define EPOLLERR (1U << 3)
|
||||
#define EPOLLHUP (1U << 4)
|
||||
#define EPOLLRDNORM (1U << 6)
|
||||
#define EPOLLRDBAND (1U << 7)
|
||||
#define EPOLLWRNORM (1U << 8)
|
||||
#define EPOLLWRBAND (1U << 9)
|
||||
#define EPOLLMSG (1U << 10)
|
||||
#define EPOLLRDHUP (1U << 13)
|
||||
#define EPOLLONESHOT (1U << 31)
|
||||
|
||||
#define EPOLL_CTL_ADD 1
|
||||
#define EPOLL_CTL_MOD 2
|
||||
#define EPOLL_CTL_DEL 3
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef uintptr_t SOCKET;
|
||||
|
||||
typedef union epoll_data {
|
||||
void* ptr;
|
||||
int fd;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
SOCKET sock; /* Windows specific */
|
||||
HANDLE hnd; /* Windows specific */
|
||||
} epoll_data_t;
|
||||
|
||||
struct epoll_event {
|
||||
uint32_t events; /* Epoll events and flags */
|
||||
epoll_data_t data; /* User data variable */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WEPOLL_EXPORT HANDLE epoll_create(int size);
|
||||
WEPOLL_EXPORT HANDLE epoll_create1(int flags);
|
||||
|
||||
WEPOLL_EXPORT int epoll_close(HANDLE ephnd);
|
||||
|
||||
WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd,
|
||||
int op,
|
||||
SOCKET sock,
|
||||
struct epoll_event* event);
|
||||
|
||||
WEPOLL_EXPORT int epoll_wait(HANDLE ephnd,
|
||||
struct epoll_event* events,
|
||||
int maxevents,
|
||||
int timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* WEPOLL_H_ */
|
||||
BIN
mariadbcpp.dll
Normal file
BIN
mariadbcpp.dll
Normal file
Binary file not shown.
|
|
@ -6,16 +6,14 @@ Please see [the module guide on the wiki](https://github.com/LandSandBoat/server
|
|||
|
||||
## Era Accuracy Modules
|
||||
|
||||
Lua era-accuracy modules live under `era/lua/` and mirror the main `scripts/` tree where practical. These modules should use `xi.module.isContentEnabled(contentTag)` to decide whether an era override should register. If the relevant content is enabled, return a data-only table such as `{ name = moduleName }`.
|
||||
When creating modules to revert or adjust content for era accuracy, place them in the folder corresponding to the expansion when the change was introduced:
|
||||
|
||||
Common content tags are:
|
||||
- cop/ : Chains of Promathia (September 2004 - March 2006)
|
||||
- toau/ : Treasures of Aht Urhgan (April 2006 - October 2007)
|
||||
- wotg/ : Wings of the Goddess (November 2007 - May 2010)
|
||||
- abyssea/ : Abyssea Add-ons (June 2010 - February 2013)
|
||||
- soa/ : Seekers of Adoulin (March 2013 - April 2015)
|
||||
- rov/ : Rhapsodies of Vana'diel (May 2015 - July 2020)
|
||||
- tvr/ : The Voracious Resurgence (August 2020 - Present)
|
||||
|
||||
- COP : Chains of Promathia (September 2004 - March 2006)
|
||||
- TOAU : Treasures of Aht Urhgan (April 2006 - October 2007)
|
||||
- WOTG : Wings of the Goddess (November 2007 - May 2010)
|
||||
- ABYSSEA : Abyssea Add-ons (June 2010 - February 2013)
|
||||
- SOA : Seekers of Adoulin (March 2013 - April 2015)
|
||||
- ROV : Rhapsodies of Vana'diel (May 2015 - July 2020)
|
||||
- TVR : The Voracious Resurgence (August 2020 - Present)
|
||||
|
||||
For example, if a Lua module reverts a December 2010 change, place it in the matching mirrored path under `era/lua/` and guard its override with `not xi.module.isContentEnabled('ABYSSEA')`.
|
||||
For example, if a change occurred in December 2010 and you want a module to revert it, place it in the abyssea/ folder.
|
||||
|
|
|
|||
|
|
@ -4,15 +4,7 @@
|
|||
-----------------------------------
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(06/21/2010)
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local moduleName = 'cop_level_caps'
|
||||
|
||||
if xi.module.isContentEnabled('ABYSSEA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
local m = Module:new('cop_level_caps')
|
||||
|
||||
-- Apply level caps after server initialization when all battlefields are loaded
|
||||
m:addOverride('xi.server.onServerStart', function()
|
||||
|
|
@ -89,7 +89,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.Zone.onInitialize', function(zone)
|
|||
|
||||
-- First-time setup.
|
||||
if hnmPopTime == 0 then
|
||||
hnmPopTime = currentTime + math.randomInt(1, 48) * 1800
|
||||
hnmPopTime = currentTime + math.random(1, 48) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Fafnir', hnmPopTime) -- Save pop time.
|
||||
end
|
||||
|
|
@ -99,7 +99,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.Zone.onInitialize', function(zone)
|
|||
|
||||
if
|
||||
hnmKillCount > 3 and
|
||||
(math.randomInt(1, 5) == 3 or hnmKillCount > 6)
|
||||
(math.random(1, 5) == 3 or hnmKillCount > 6)
|
||||
then
|
||||
monster = dragonsAeryID.mob.NIDHOGG
|
||||
end
|
||||
|
|
@ -122,7 +122,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.mobs.Fafnir.onMobDespawn', function
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
local hnmKillCount = GetServerVariable('[HNM]Fafnir_C') + 1
|
||||
|
||||
SetServerVariable('[HNM]Fafnir', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
|
|
@ -133,7 +133,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.mobs.Fafnir.onMobDespawn', function
|
|||
|
||||
if
|
||||
hnmKillCount > 3 and
|
||||
(math.randomInt(1, 5) == 3 or hnmKillCount > 6)
|
||||
(math.random(1, 5) == 3 or hnmKillCount > 6)
|
||||
then
|
||||
monster = dragonsAeryID.mob.NIDHOGG
|
||||
end
|
||||
|
|
@ -146,7 +146,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.mobs.Nidhogg.onMobDespawn', functio
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Fafnir', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
SetServerVariable('[HNM]Fafnir_C', 0) -- Save kill count.
|
||||
|
|
@ -222,7 +222,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.Zone.onInitialize', function(z
|
|||
|
||||
-- First-time setup.
|
||||
if hnmPopTime == 0 then
|
||||
hnmPopTime = currentTime + math.randomInt(1, 48) * 1800
|
||||
hnmPopTime = currentTime + math.random(1, 48) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Adamantoise', hnmPopTime) -- Save pop time.
|
||||
end
|
||||
|
|
@ -232,7 +232,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.Zone.onInitialize', function(z
|
|||
|
||||
if
|
||||
hnmKillCount > 3 and
|
||||
(math.randomInt(1, 5) == 3 or hnmKillCount > 6)
|
||||
(math.random(1, 5) == 3 or hnmKillCount > 6)
|
||||
then
|
||||
monster = valleySorrowsID.mob.ASPIDOCHELONE
|
||||
end
|
||||
|
|
@ -255,7 +255,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.mobs.Adamantoise.onMobDespawn'
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
local hnmKillCount = GetServerVariable('[HNM]Adamantoise_C') + 1
|
||||
|
||||
SetServerVariable('[HNM]Adamantoise', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
|
|
@ -266,7 +266,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.mobs.Adamantoise.onMobDespawn'
|
|||
|
||||
if
|
||||
hnmKillCount > 3 and
|
||||
(math.randomInt(1, 5) == 3 or hnmKillCount > 6)
|
||||
(math.random(1, 5) == 3 or hnmKillCount > 6)
|
||||
then
|
||||
monster = valleySorrowsID.mob.ASPIDOCHELONE
|
||||
end
|
||||
|
|
@ -279,7 +279,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.mobs.Aspidochelone.onMobDespaw
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Adamantoise', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
SetServerVariable('[HNM]Adamantoise_C', 0) -- Save kill count.
|
||||
|
|
@ -355,7 +355,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.Zone.onInitialize', function(
|
|||
|
||||
-- First-time setup.
|
||||
if hnmPopTime == 0 then
|
||||
hnmPopTime = currentTime + math.randomInt(1, 48) * 1800
|
||||
hnmPopTime = currentTime + math.random(1, 48) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Behemoth', hnmPopTime) -- Save pop time.
|
||||
end
|
||||
|
|
@ -365,7 +365,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.Zone.onInitialize', function(
|
|||
|
||||
if
|
||||
hnmKillCount > 3 and
|
||||
(math.randomInt(1, 5) == 3 or hnmKillCount > 6)
|
||||
(math.random(1, 5) == 3 or hnmKillCount > 6)
|
||||
then
|
||||
monster = behemothDomID.mob.KING_BEHEMOTH
|
||||
end
|
||||
|
|
@ -388,7 +388,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.mobs.Behemoth.onMobDespawn',
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
local hnmKillCount = GetServerVariable('[HNM]Behemoth_C') + 1
|
||||
|
||||
SetServerVariable('[HNM]Behemoth', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
|
|
@ -399,7 +399,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.mobs.Behemoth.onMobDespawn',
|
|||
|
||||
if
|
||||
hnmKillCount > 3 and
|
||||
(math.randomInt(1, 5) == 3 or hnmKillCount > 6)
|
||||
(math.random(1, 5) == 3 or hnmKillCount > 6)
|
||||
then
|
||||
monster = behemothDomID.mob.KING_BEHEMOTH
|
||||
end
|
||||
|
|
@ -412,7 +412,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.mobs.King_Behemoth.onMobDespa
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Behemoth', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
SetServerVariable('[HNM]Behemoth_C', 0) -- Save kill count.
|
||||
|
|
|
|||
|
|
@ -5,13 +5,7 @@
|
|||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local moduleName = 'lamian_fang_key_tally_timer'
|
||||
|
||||
if xi.module.isContentEnabled('ABYSSEA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
local m = Module:new('lamian_fang_key_tally_timer')
|
||||
|
||||
m:addOverride('xi.zones.Caedarva_Mire.npcs.qm8.onTrigger', function(player, npc)
|
||||
local ID = zones[xi.zone.CAEDARVA_MIRE]
|
||||
59
modules/abyssea/lua/helm_adjustments.lua
Normal file
59
modules/abyssea/lua/helm_adjustments.lua
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
-----------------------------------
|
||||
-- Module: HELM Adjustments (Abyssea Era)
|
||||
-- Desc: Removes items that were added to existing zone HELM rewards during the Abyssea era
|
||||
-- Source:
|
||||
-- Aquilaria Log: https://www.bg-wiki.com/ffxi/September_2010_Version_Update_Changes#Usable_Items
|
||||
-- Butterpear and Kapor Log: https://www.bg-wiki.com/ffxi/September_2011_Version_Update_Changes#Wings_of_the_Goddess_Quests
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local m = Module:new('abyssea_helm_adjustments')
|
||||
|
||||
local removals =
|
||||
{
|
||||
[xi.helmType.LOGGING] =
|
||||
{
|
||||
[xi.zone.YHOATOR_JUNGLE] =
|
||||
{
|
||||
xi.item.BUTTERPEAR,
|
||||
xi.item.AQUILARIA_LOG,
|
||||
xi.item.KAPOR_LOG,
|
||||
},
|
||||
|
||||
[xi.zone.YUHTUNGA_JUNGLE] =
|
||||
{
|
||||
xi.item.AQUILARIA_LOG,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local removeItems = function(drops, itemsToRemove)
|
||||
local removeSet = {}
|
||||
for _, itemId in ipairs(itemsToRemove) do
|
||||
removeSet[itemId] = true
|
||||
end
|
||||
|
||||
local filtered = {}
|
||||
for _, entry in ipairs(drops) do
|
||||
if not removeSet[entry[2]] then
|
||||
filtered[#filtered + 1] = entry
|
||||
end
|
||||
end
|
||||
|
||||
return filtered
|
||||
end
|
||||
|
||||
-- Apply removals to xi.helm.dataTable.
|
||||
for helmType, zones in pairs(removals) do
|
||||
local helmData = xi.helm.dataTable[helmType]
|
||||
if helmData then
|
||||
for zoneId, itemsToRemove in pairs(zones) do
|
||||
local zoneData = helmData.zone[zoneId]
|
||||
if zoneData and zoneData.drops then
|
||||
zoneData.drops = removeItems(zoneData.drops, itemsToRemove)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
||||
596
modules/abyssea/lua/job_adjustments.lua
Normal file
596
modules/abyssea/lua/job_adjustments.lua
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
-----------------------------------
|
||||
-- Module: Job Adjustments (Abyssea Era)
|
||||
-- Desc: Removes traits/abilities/effects that were added to jobs during the Abyssea era
|
||||
-----------------------------------
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012)
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local m = Module:new('abyssea_job_adjustments')
|
||||
|
||||
-----------------------------------
|
||||
-- Warrior
|
||||
-----------------------------------
|
||||
|
||||
-- Warrior's Charge: Remove Triple Attack bonus
|
||||
m:addOverride('xi.effects.warriors_charge.onEffectGain', function(target, effect)
|
||||
effect:addMod(xi.mod.DOUBLE_ATTACK, 100)
|
||||
end)
|
||||
|
||||
-- Warrior's Charge: Apply merit recast reduction
|
||||
m:addOverride('xi.job_utils.warrior.useWarriorsCharge', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.WARRIORS_CHARGE) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
player:addStatusEffect(xi.effect.WARRIORS_CHARGE, { power = 1, duration = 60, origin = player })
|
||||
|
||||
return xi.effect.WARRIORS_CHARGE
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- White Mage
|
||||
-----------------------------------
|
||||
|
||||
-- Martyr: Apply merit recast reduction, remove merit healing bonus
|
||||
m:addOverride('xi.job_utils.white_mage.useMartyr', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.MARTYR) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
local damageHP = math.floor(player:getHP() * 0.25)
|
||||
local healHP = damageHP * 2
|
||||
healHP = utils.clamp(healHP, 0, target:getMaxHP() - target:getHP())
|
||||
|
||||
-- If stoneskin is present, it should absorb damage
|
||||
damageHP = utils.handleStoneskin(player, damageHP)
|
||||
player:delHP(damageHP)
|
||||
target:addHP(healHP)
|
||||
|
||||
return healHP
|
||||
end)
|
||||
|
||||
-- Devotion: Apply merit recast reduction, remove merit MP bonus
|
||||
m:addOverride('xi.job_utils.white_mage.useDevotion', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.DEVOTION) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
local damageHP = math.floor(player:getHP() * 0.25)
|
||||
local healMP = damageHP
|
||||
healMP = utils.clamp(healMP, 0, target:getMaxMP() - target:getMP())
|
||||
|
||||
-- If stoneskin is present, it should absorb damage
|
||||
damageHP = utils.handleStoneskin(player, damageHP)
|
||||
player:delHP(damageHP)
|
||||
target:addMP(healMP)
|
||||
|
||||
return healMP
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Thief
|
||||
-----------------------------------
|
||||
|
||||
-- Assassin's Charge: Remove Quadruple Attack
|
||||
m:addOverride('xi.effects.assassins_charge.onEffectGain', function(target, effect)
|
||||
effect:addMod(xi.mod.TRIPLE_ATTACK, 100)
|
||||
end)
|
||||
|
||||
-- Assassin's Charge: Reduce cooldown by merit count
|
||||
m:addOverride('xi.job_utils.thief.useAssassinsCharge', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.ASSASSINS_CHARGE) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
player:addStatusEffect(xi.effect.ASSASSINS_CHARGE, { power = 1, duration = 60, origin = player })
|
||||
|
||||
return xi.effect.ASSASSINS_CHARGE
|
||||
end)
|
||||
|
||||
-- Feint: Remove Treasure Hunter rate and reduce cooldown by merit count
|
||||
m:addOverride('xi.job_utils.thief.useFeint', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.FEINT) - 120
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
player:addStatusEffect(xi.effect.FEINT, { power = 150, duration = 60, origin = player })
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Dark Knight
|
||||
-----------------------------------
|
||||
|
||||
-- Arcane Circle: Revert duration from 3 minutes to 1 minute
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
m:addOverride('xi.job_utils.dark_knight.useArcaneCircle', function(player, target, ability)
|
||||
local duration = 60 + player:getMod(xi.mod.ARCANE_CIRCLE_DURATION)
|
||||
local power = 15
|
||||
|
||||
if player:getMainJob() ~= xi.job.DRK then
|
||||
power = 5
|
||||
end
|
||||
|
||||
power = power + player:getMod(xi.mod.ARCANE_CIRCLE_POTENCY)
|
||||
|
||||
target:addStatusEffect(xi.effect.ARCANE_CIRCLE, { power = power, duration = duration, origin = player })
|
||||
|
||||
return xi.effect.ARCANE_CIRCLE
|
||||
end)
|
||||
|
||||
-- Last Resort: Revert duration from 3 minutes to 30 seconds
|
||||
m:addOverride('xi.job_utils.dark_knight.useLastResort', function(player, target, ability)
|
||||
player:addStatusEffect(xi.effect.LAST_RESORT, { duration = 30, origin = player })
|
||||
|
||||
return xi.effect.LAST_RESORT
|
||||
end)
|
||||
|
||||
-- Dark Seal: Remove extra duration and cast speed from merits
|
||||
m:addOverride('xi.effects.dark_seal.onEffectGain', function(target, effect)
|
||||
-- Overwrites
|
||||
target:delStatusEffectSilent(xi.effect.DIVINE_EMBLEM)
|
||||
target:delStatusEffectSilent(xi.effect.DIVINE_SEAL)
|
||||
target:delStatusEffectSilent(xi.effect.ELEMENTAL_SEAL)
|
||||
end)
|
||||
|
||||
-- Dark Seal: Apply merit recast reduction
|
||||
m:addOverride('xi.job_utils.dark_knight.useDarkSeal', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.DARK_SEAL) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
player:addStatusEffect(xi.effect.DARK_SEAL, { power = 1, duration = 60, origin = player })
|
||||
|
||||
return xi.effect.DARK_SEAL
|
||||
end)
|
||||
|
||||
-- Diabolic Eye: Remove extra duration and potency from merits and apply merit recast reduction
|
||||
m:addOverride('xi.job_utils.dark_knight.useDiabolicEye', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.DIABOLIC_EYE) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
player:addStatusEffect(xi.effect.DIABOLIC_EYE, { power = 20, duration = 180, origin = player })
|
||||
|
||||
return xi.effect.DIABOLIC_EYE
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Beastmaster
|
||||
-----------------------------------
|
||||
|
||||
-- Reward: Override pet food healing values to pre-Abyssea values
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(09/08/2010)
|
||||
xi.job_utils.beastmaster.petFoodData =
|
||||
{
|
||||
[xi.item.PET_FOOD_ALPHA_BISCUIT] = { minHealing = 25, regen = 1, mndMult = 2, mndThreshold = 10 },
|
||||
[xi.item.PET_FOOD_BETA_BISCUIT] = { minHealing = 50, regen = 3, mndMult = 1, mndThreshold = 33 },
|
||||
[xi.item.PET_FOOD_GAMMA_BISCUIT] = { minHealing = 100, regen = 5, mndMult = 1, mndThreshold = 35 },
|
||||
[xi.item.PET_FOOD_DELTA_BISCUIT] = { minHealing = 150, regen = 8, mndMult = 2, mndThreshold = 40 },
|
||||
[xi.item.PET_FOOD_EPSILON_BISCUIT] = { minHealing = 300, regen = 11, mndMult = 2, mndThreshold = 45 },
|
||||
[xi.item.PET_FOOD_ZETA_BISCUIT] = { minHealing = 350, regen = 14, mndMult = 3, mndThreshold = 45 },
|
||||
}
|
||||
|
||||
-- Feral Howl: Apply merit recast reduction, remove extra accuracy from merits
|
||||
m:addOverride('xi.job_utils.beastmaster.useFeralHowl', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.FERAL_HOWL) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
if
|
||||
not xi.data.statusEffect.isTargetImmune(target, xi.effect.TERROR, xi.element.DARK) and
|
||||
not xi.data.statusEffect.isTargetResistant(player, target, xi.effect.TERROR) and
|
||||
not xi.data.statusEffect.isEffectNullified(target, xi.effect.TERROR, 0)
|
||||
then
|
||||
local resistanceRate = xi.combat.magicHitRate.calculateResistRate(player, target, 0, 0, xi.skillRank.B_MINUS, xi.element.DARK, xi.mod.CHR, xi.effect.TERROR)
|
||||
|
||||
if xi.data.statusEffect.isResistRateSuccessfull(xi.effect.TERROR, resistanceRate, 0) then
|
||||
target:addStatusEffect(xi.effect.TERROR, { power = 1, duration = 10 * resistanceRate, origin = player })
|
||||
end
|
||||
end
|
||||
|
||||
return xi.effect.TERROR
|
||||
end)
|
||||
|
||||
-- Killer Insinct: Apply merit recast reduction, remove extra duration from merits
|
||||
m:addOverride('xi.job_utils.beastmaster.useKillerInstinct', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.KILLER_INSTINCT) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
-- Notes: Pet ecosystem is assigned to the subPower, then mapped to the correct killer mod in the effect script.
|
||||
local pet = player:getPet()
|
||||
local petEcosystem = pet:getEcosystem()
|
||||
local power = 10
|
||||
|
||||
target:addStatusEffect(xi.effect.KILLER_INSTINCT, { power = power, duration = 60, origin = player, subPower = petEcosystem })
|
||||
|
||||
return xi.effect.KILLER_INSTINCT
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Samurai
|
||||
-----------------------------------
|
||||
|
||||
-- Warding Circle: Revert duration from 3 minutes to 1 minute
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
m:addOverride('xi.job_utils.samurai.useWardingCircle', function(player, target, ability)
|
||||
local duration = 60 + player:getMod(xi.mod.WARDING_CIRCLE_DURATION)
|
||||
local power = 15
|
||||
|
||||
if player:getMainJob() ~= xi.job.SAM then
|
||||
power = 5
|
||||
end
|
||||
|
||||
power = power + player:getMod(xi.mod.WARDING_CIRCLE_POTENCY)
|
||||
|
||||
target:addStatusEffect(xi.effect.WARDING_CIRCLE, { power = power, duration = duration, origin = player })
|
||||
|
||||
return xi.effect.WARDING_CIRCLE
|
||||
end)
|
||||
|
||||
-- Blade Bash: Apply merit recast reduction, remove extra plague duration from merits
|
||||
m:addOverride('xi.job_utils.samurai.useBladeBash', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.BLADE_BASH) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
-- Damage
|
||||
-- TODO: Verify damage formula and DRK interaction
|
||||
local jobLevel = utils.getActiveJobLevel(player, xi.job.DRK)
|
||||
local damage = math.floor((jobLevel + 11) / 4 + player:getMod(xi.mod.WEAPON_BASH))
|
||||
damage = utils.handleStoneskin(target, damage)
|
||||
target:takeDamage(damage, player, xi.attackType.PHYSICAL, xi.damageType.BLUNT)
|
||||
target:updateEnmityFromDamage(player, damage)
|
||||
|
||||
-- Stun
|
||||
if
|
||||
not xi.data.statusEffect.isTargetImmune(target, xi.effect.STUN, xi.element.THUNDER) and
|
||||
not xi.data.statusEffect.isTargetResistant(player, target, xi.effect.STUN) and
|
||||
not xi.data.statusEffect.isEffectNullified(target, xi.effect.STUN, 0)
|
||||
then
|
||||
local resistanceRate = xi.combat.magicHitRate.calculateResistRate(player, target, 0, 0, xi.skillRank.A_PLUS, xi.element.THUNDER, xi.mod.INT, xi.effect.STUN, 0)
|
||||
if xi.data.statusEffect.isResistRateSuccessfull(xi.effect.STUN, resistanceRate, 0) then
|
||||
target:addStatusEffect(xi.effect.STUN, { power = 1, duration = 6 * resistanceRate, origin = player })
|
||||
end
|
||||
end
|
||||
|
||||
-- Plague
|
||||
if
|
||||
not xi.data.statusEffect.isTargetImmune(target, xi.effect.PLAGUE, xi.element.FIRE) and
|
||||
not xi.data.statusEffect.isTargetResistant(player, target, xi.effect.PLAGUE) and
|
||||
not xi.data.statusEffect.isEffectNullified(target, xi.effect.PLAGUE, 0)
|
||||
then
|
||||
local resistanceRate = xi.combat.magicHitRate.calculateResistRate(player, target, 0, 0, xi.skillRank.A_PLUS, xi.element.FIRE, xi.mod.INT, xi.effect.PLAGUE, 0)
|
||||
if xi.data.statusEffect.isResistRateSuccessfull(xi.effect.PLAGUE, resistanceRate, 0) then
|
||||
target:addStatusEffect(xi.effect.PLAGUE, { power = 5, duration = 15 * resistanceRate, origin = player })
|
||||
end
|
||||
end
|
||||
|
||||
-- Animation
|
||||
local animationTable =
|
||||
{
|
||||
-- [weapon type] = animation ID
|
||||
[xi.skill.GREAT_SWORD ] = 201,
|
||||
[xi.skill.GREAT_KATANA] = 201,
|
||||
[xi.skill.GREAT_AXE ] = 202,
|
||||
[xi.skill.SCYTHE ] = 202,
|
||||
[xi.skill.STAFF ] = 202,
|
||||
[xi.skill.POLEARM ] = 203,
|
||||
}
|
||||
|
||||
local animation = animationTable[player:getWeaponSkillType(xi.slot.MAIN)] or 0
|
||||
action:setAnimation(target:getID(), animation)
|
||||
|
||||
ability:setMsg(xi.msg.basic.JA_DAMAGE)
|
||||
|
||||
return damage
|
||||
end)
|
||||
|
||||
-- Shikikoyo: Apply merit recast reduction, remove extra TP sharing from merits
|
||||
m:addOverride('xi.job_utils.samurai.useShikikoyo', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.SHIKIKOYO) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
local pTP = player:getTP() - 1000
|
||||
pTP = utils.clamp(pTP, 0, 3000 - target:getTP())
|
||||
|
||||
player:setTP(1000)
|
||||
target:setTP(target:getTP() + pTP)
|
||||
|
||||
return pTP
|
||||
end)
|
||||
|
||||
-- Hasso: Remove Zanshin bonus
|
||||
m:addOverride('xi.effects.hasso.onEffectGain', function(target, effect)
|
||||
effect:addMod(xi.mod.TWOHAND_STR, effect:getPower())
|
||||
effect:addMod(xi.mod.TWOHAND_HASTE_ABILITY, 1000)
|
||||
effect:addMod(xi.mod.TWOHAND_ACC, 10)
|
||||
end)
|
||||
|
||||
-- Seigan: Remove Zanshin-based counter bonus
|
||||
m:addOverride('xi.effects.seigan.onEffectGain', function(target, effect)
|
||||
local jpValue = target:getJobPointLevel(xi.jp.SEIGAN_EFFECT)
|
||||
|
||||
effect:addMod(xi.mod.DEF, jpValue * 3)
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Ranger
|
||||
-----------------------------------
|
||||
|
||||
-- Flashy Shot: Apply merit recast reduction
|
||||
m:addOverride('xi.job_utils.ranger.useFlashyShot', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.FLASHY_SHOT) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
player:addStatusEffect(xi.effect.FLASHY_SHOT, { power = 1, duration = 60, origin = player })
|
||||
|
||||
return xi.effect.FLASHY_SHOT
|
||||
end)
|
||||
|
||||
-- Flashy Shot Effect: Add level correction bypass
|
||||
m:addOverride('xi.effects.flashy_shot.onEffectGain', function(target, effect)
|
||||
effect:addMod(xi.mod.ENMITY, 50)
|
||||
effect:addMod(xi.mod.RA_IGNORE_LVL_DIFF, 1)
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Dragoon
|
||||
-----------------------------------
|
||||
|
||||
-- Ancient Circle: Revert duration from 3 minutes to 1 minute
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
m:addOverride('xi.job_utils.dragoon.useAncientCircle', function(player, target, ability)
|
||||
local duration = 60 + player:getMod(xi.mod.ANCIENT_CIRCLE_DURATION)
|
||||
local power = 15
|
||||
|
||||
if player:getMainJob() ~= xi.job.DRG then
|
||||
power = 5
|
||||
end
|
||||
|
||||
power = power + player:getMod(xi.mod.ANCIENT_CIRCLE_POTENCY)
|
||||
|
||||
ability:setMsg(xi.msg.basic.USES_ABILITY_FORTIFIED_DRAGONS)
|
||||
|
||||
target:addStatusEffect(xi.effect.ANCIENT_CIRCLE, { power = power, duration = duration, origin = player })
|
||||
|
||||
return xi.effect.ANCIENT_CIRCLE
|
||||
end)
|
||||
|
||||
-- Spirit Surge: Revert haste to be HASTE_MAGIC instead of HASTE_ABILITY
|
||||
-- Also removes ATK and DEF bonuses which are removed in SoA module
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
m:addOverride('xi.effects.spirit_surge.onEffectGain', function(target, effect)
|
||||
effect:addMod(xi.mod.HP, effect:getPower())
|
||||
target:updateHealth()
|
||||
|
||||
effect:addMod(xi.mod.STR, effect:getSubPower())
|
||||
effect:addMod(xi.mod.ACC, 50)
|
||||
effect:addMod(xi.mod.HASTE_MAGIC, 2500)
|
||||
effect:addMod(xi.mod.MAIN_DMG_RATING, target:getJobPointLevel(xi.jp.SPIRIT_SURGE_EFFECT))
|
||||
end)
|
||||
|
||||
-- Spirit Surge + Super Jump: Revert enmity reduction from 100% to 50%
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012)
|
||||
m:addOverride('xi.job_utils.dragoon.superJumpSurgeEffect', function(player, target)
|
||||
if player:hasStatusEffect(xi.effect.SPIRIT_SURGE) then
|
||||
local minDistance = 9999
|
||||
local closestPartyMember = nil
|
||||
|
||||
-- Find the closest party member
|
||||
local party = player:getPartyWithTrusts()
|
||||
for _, member in pairs(party) do
|
||||
local distance = member:checkDistance(player)
|
||||
if
|
||||
member:getID() ~= player:getID() and
|
||||
not member:isDead() and
|
||||
(distance < minDistance or closestPartyMember == nil)
|
||||
then
|
||||
closestPartyMember = member
|
||||
minDistance = distance
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: verify conditions for how close the dragoon needs to be to the mob, if at all
|
||||
if
|
||||
closestPartyMember and
|
||||
closestPartyMember:isBehind(player) and
|
||||
(player:checkDistance(target) < closestPartyMember:checkDistance(target))
|
||||
then
|
||||
if target:isMob() then
|
||||
target:lowerEnmity(closestPartyMember, 50)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Deep Breathing: Apply merit recast reduction instead of breath power bonus
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012)
|
||||
m:addOverride('xi.job_utils.dragoon.useDeepBreathing', function(player, target, ability, action)
|
||||
local recastReduction = player:getMerit(xi.merit.DEEP_BREATHING) - 150
|
||||
action:setRecast(action:getRecast() - recastReduction)
|
||||
|
||||
local wyvern = player:getPet()
|
||||
|
||||
if wyvern and wyvern:getPetID() == xi.petId.WYVERN then
|
||||
wyvern:addStatusEffect(xi.effect.MAGIC_ATK_BOOST, { duration = 180, origin = player })
|
||||
end
|
||||
end)
|
||||
|
||||
-- Deep Breathing Bonus: Remove merit scaling, use flat base bonus only
|
||||
m:addOverride('xi.job_utils.dragoon.getDeepBreathingBonus', function(wyvern, master, isHealing)
|
||||
local bonus = 0
|
||||
local hadEffect = wyvern:hasStatusEffect(xi.effect.MAGIC_ATK_BOOST)
|
||||
|
||||
if hadEffect then
|
||||
bonus = isHealing and 37.5 or 0.75
|
||||
|
||||
wyvern:delStatusEffect(xi.effect.MAGIC_ATK_BOOST)
|
||||
end
|
||||
|
||||
return bonus
|
||||
end)
|
||||
|
||||
-- Spirit Link: Revert TP transfer from wyvern to master and removes regen
|
||||
-- TP Transfer Source: https://www.bg-wiki.com/ffxi/Version_Update_(06/21/2010)
|
||||
-- Regen Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012)
|
||||
m:addOverride('xi.job_utils.dragoon.useSpiritLink', function(player, target, ability, action)
|
||||
local wyvern = player:getPet()
|
||||
local playerHP = player:getHP()
|
||||
|
||||
xi.job_utils.dragoon.checkForRemovableEffectsOnSpiritLink(player, wyvern)
|
||||
|
||||
-- Empathy: copy status effects and grant wyvern EXP
|
||||
xi.job_utils.dragoon.applyEmpathyBonus(player, wyvern)
|
||||
|
||||
-- Pre-Abyssea: No TP transfer from wyvern to master
|
||||
|
||||
-- Calculate drain amount.
|
||||
local drainAmount = 0
|
||||
|
||||
if wyvern:getHP() ~= wyvern:getMaxHP() then
|
||||
drainAmount = (math.random(25, 35) / 100) * playerHP
|
||||
drainAmount = drainAmount * (1 - (0.01 * player:getJobPointLevel(xi.jp.SPIRIT_LINK_EFFECT)))
|
||||
end
|
||||
|
||||
-- Handle Stoneskin.
|
||||
local stoneskinPower = 0
|
||||
|
||||
if player:hasStatusEffect(xi.effect.STONESKIN) then
|
||||
stoneskinPower = player:getMod(xi.mod.STONESKIN)
|
||||
|
||||
-- If stoneskin is more powerfull than the amount to be drained.
|
||||
if stoneskinPower > drainAmount then
|
||||
local effect = player:getStatusEffect(xi.effect.STONESKIN)
|
||||
effect:setPower(effect:getPower() - drainAmount) -- Fixes the status effect so when it ends it uses the new power instead of old.
|
||||
player:delMod(xi.mod.STONESKIN, drainAmount) -- Removes the amount from the mod.
|
||||
|
||||
-- If stoneskin is as powerful or less than the amount to be drained.
|
||||
else
|
||||
player:delStatusEffect(xi.effect.STONESKIN)
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle master damage and pet healing.
|
||||
player:takeDamage(drainAmount - stoneskinPower)
|
||||
|
||||
-- Pre-September 2015: Healing formula includes MND and wyvern level components.
|
||||
-- Source: https://wiki.ffo.jp/html/1897.html https://www.bg-wiki.com/ffxi/Spirit_Link
|
||||
local playerMND = player:getStat(xi.mod.MND)
|
||||
local alpha = wyvern:getMainLvl() * 0.7
|
||||
local healPet = (drainAmount + playerMND + alpha) * 2
|
||||
|
||||
if player:getEquipID(xi.slot.HEAD) == xi.item.DRACHEN_ARMET_P1 then
|
||||
healPet = healPet + 15
|
||||
end
|
||||
|
||||
-- Spirit Link is self target but reports effect on Wyvern.
|
||||
action:ID(player:getID(), wyvern:getID())
|
||||
|
||||
return wyvern:addHP(healPet) -- add the hp to wyvern
|
||||
end)
|
||||
|
||||
-- Empathy: Revert Spirit Link granting wyvern 200 EXP per Empathy merit level
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(05/15/2012)
|
||||
m:addOverride('xi.job_utils.dragoon.applyEmpathyBonus', function(player, wyvern)
|
||||
local empathyTotal = player:getMerit(xi.merit.EMPATHY)
|
||||
|
||||
if empathyTotal > 0 then
|
||||
local validEffects = {}
|
||||
local i = 0
|
||||
local effects = player:getStatusEffects()
|
||||
local copyi = 0
|
||||
|
||||
for _, effect in pairs(effects) do
|
||||
if effect:hasEffectFlag(xi.effectFlag.EMPATHY) then
|
||||
validEffects[i + 1] = effect
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
if i < empathyTotal then
|
||||
empathyTotal = i
|
||||
elseif i > empathyTotal then
|
||||
validEffects = xi.job_utils.dragoon.cutEmpathyEffectTable(validEffects, i, empathyTotal)
|
||||
end
|
||||
|
||||
local copyEffect = nil
|
||||
while copyi < empathyTotal do
|
||||
copyEffect = validEffects[copyi + 1]
|
||||
if wyvern:hasStatusEffect(copyEffect:getEffectType()) then
|
||||
wyvern:delStatusEffectSilent(copyEffect:getEffectType())
|
||||
end
|
||||
|
||||
wyvern:copyStatusEffect(copyEffect)
|
||||
copyi = copyi + 1
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Wyvern Spawn: Revert innate -40% DT and reduce status breath table
|
||||
-- DT Source: https://www.bg-wiki.com/ffxi/Version_Update_(09/19/2011)
|
||||
-- Status Breath Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
m:addOverride('xi.pets.wyvern.onMobSpawn', function(mob)
|
||||
super(mob)
|
||||
|
||||
local master = mob:getMaster()
|
||||
|
||||
-- Revert innate -40% DT
|
||||
mob:addMod(xi.mod.DMG, 4000)
|
||||
|
||||
-- Determine if wyvern is DEFENSIVE type (status breath on WS)
|
||||
local defensiveJobs =
|
||||
{
|
||||
[xi.job.WHM] = true,
|
||||
[xi.job.BLM] = true,
|
||||
[xi.job.RDM] = true,
|
||||
[xi.job.SMN] = true,
|
||||
[xi.job.BLU] = true,
|
||||
[xi.job.SCH] = true,
|
||||
[xi.job.GEO] = true,
|
||||
}
|
||||
|
||||
if defensiveJobs[master:getSubJob()] then
|
||||
-- Replace WS listener with pre-2012 status breath table
|
||||
master:removeListener('PET_WYVERN_WS')
|
||||
|
||||
local removeBreathTable =
|
||||
{
|
||||
{ 40, xi.jobAbility.REMOVE_PARALYSIS, { xi.effect.PARALYSIS } },
|
||||
{ 20, xi.jobAbility.REMOVE_BLINDNESS, { xi.effect.BLINDNESS } },
|
||||
{ 1, xi.jobAbility.REMOVE_POISON, { xi.effect.POISON } },
|
||||
}
|
||||
|
||||
local breathRange = 14
|
||||
|
||||
local function doStatusBreath(target, player)
|
||||
local wyvern = player:getPet()
|
||||
|
||||
for _, v in pairs(removeBreathTable) do
|
||||
local minLevel = v[1]
|
||||
local ability = v[2]
|
||||
local statuses = v[3]
|
||||
|
||||
if wyvern:getMainLvl() >= minLevel then
|
||||
for _, effect in pairs(statuses) do
|
||||
if
|
||||
target:hasStatusEffect(effect) and
|
||||
wyvern:checkDistance(target) <= breathRange
|
||||
then
|
||||
wyvern:usePetAbility(ability, target)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
master:addListener('WEAPONSKILL_USE', 'PET_WYVERN_WS', function(player, target, skillid)
|
||||
if not doStatusBreath(player, player) then
|
||||
local party = player:getParty()
|
||||
for _, member in pairs(party) do
|
||||
if doStatusBreath(member, player) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
return m
|
||||
104
modules/abyssea/lua/puppetmaster/analyzer.lua
Normal file
104
modules/abyssea/lua/puppetmaster/analyzer.lua
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
-----------------------------------
|
||||
-- Analyzer (Pre 2012)
|
||||
-- Reduces damage taken from repeated TP moves by 10%, with an additional 10% per Earth Maneuver.
|
||||
-- Resets after a new skill is used.
|
||||
-- Was changed March 27th, 2012 to analyze multiple TP moves based off earth maneuvers, with a 40% damage reduction.
|
||||
-- NOTE: This module touches both the attachment, and the combat utility. Both are needed for this attachment to function correctly.
|
||||
-- https://wiki.ffo.jp/html/10746.html
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local m = Module:new('era_analyzer')
|
||||
|
||||
-----------------------------------
|
||||
-- Attachment Module
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onEquip', function(pet, attachment)
|
||||
-- Analyzed skills do not carry over between zones, onEquip is called when rebuilding the automaton after zoning.
|
||||
pet:setLocalVar('analyzedSkill1', 0)
|
||||
|
||||
pet:addListener('WEAPONSKILL_TAKE', 'ANALYZER_WEAPONSKILL_TAKE', function(mob, target, skill, tp, action)
|
||||
local analyzerModifier = target:getMod(xi.mod.AUTO_ANALYZER)
|
||||
local incomingSkill = skill:getID()
|
||||
|
||||
-- If Analyzer modifier is 0, return. (Should be impossible since the attachment wouldn't be equipped, but just in case.)
|
||||
if analyzerModifier <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local analyzedSkill = target:getLocalVar('analyzedSkill1')
|
||||
|
||||
-- If the incoming skill is the one we have already analyzed, return.
|
||||
if incomingSkill == analyzedSkill then
|
||||
return
|
||||
end
|
||||
|
||||
-- If the incoming skill is different from the analyzed skill, update the analyzed skill ID.
|
||||
if incomingSkill ~= analyzedSkill then
|
||||
target:setLocalVar('analyzedSkill1', incomingSkill)
|
||||
end
|
||||
end)
|
||||
|
||||
xi.automaton.onAttachmentEquip(pet, attachment)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onUnequip', function(pet, attachment)
|
||||
-- Clear analyzed skill on unequip, and remove the listener.
|
||||
pet:setLocalVar('analyzedSkill1', 0)
|
||||
|
||||
pet:removeListener('ANALYZER_WEAPONSKILL_TAKE')
|
||||
|
||||
xi.automaton.onAttachmentUnequip(pet, attachment)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onManeuverGain', function(pet, attachment, maneuvers)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onManeuverLose', function(pet, attachment, maneuvers)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onUpdate', function(pet, attachment, maneuvers)
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Combat Utility Override
|
||||
-----------------------------------
|
||||
m:addOverride('utils.handleAutomatonAutoAnalyzer', function(actor, skill, damage)
|
||||
local analyzerModifier = actor:getMod(xi.mod.AUTO_ANALYZER)
|
||||
|
||||
-- If no Analyzer equipped, return unmodified damage.
|
||||
if analyzerModifier <= 0 then
|
||||
return damage
|
||||
end
|
||||
|
||||
local automatonId = actor:getID()
|
||||
|
||||
-- If we can't track this automaton, return unmodified damage.
|
||||
if not automatonId then
|
||||
return damage
|
||||
end
|
||||
|
||||
local automatonMaster = actor:getMaster()
|
||||
|
||||
-- If we can't get the master of this automaton, return unmodified damage.
|
||||
if not automatonMaster then
|
||||
return damage
|
||||
end
|
||||
|
||||
local incomingSkill = skill:getID()
|
||||
local analyzedSkill = actor:getLocalVar('analyzedSkill1')
|
||||
|
||||
-- If the incoming skill is the same ID as the analyzed skill, apply the Analyzer damage reduction and return.
|
||||
if incomingSkill == analyzedSkill then
|
||||
local earthManeuvers = automatonMaster:countEffect(xi.effect.EARTH_MANEUVER)
|
||||
local damageReduction = 10 + 10 * earthManeuvers
|
||||
|
||||
return math.floor(damage * (100 - damageReduction) / 100)
|
||||
end
|
||||
|
||||
-- If we somehow make it here, return unmodified damage.
|
||||
return damage
|
||||
end)
|
||||
|
||||
return m
|
||||
123
modules/abyssea/lua/puppetmaster/eraser.lua
Normal file
123
modules/abyssea/lua/puppetmaster/eraser.lua
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
-----------------------------------
|
||||
-- Eraser (Pre-2011)
|
||||
-- Removes up to 3 status effects from the Automaton or its Master based on the number of Light Maneuvers active.
|
||||
-- Consumes all maneuvers on use.
|
||||
-- Eraser cannot remove Venom, Death Sentence, Charm or Gradual Petrification.
|
||||
-- Prioritizes removing effects from the Automaton over the Master.
|
||||
-- Updated to consume only Light Maneuvers on December 15th, 2011.
|
||||
-- Updated to consume no maneuvers on March 11th, 2019.
|
||||
-- https://wiki.ffo.jp/html/5365.html
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local m = Module:new('era_eraser')
|
||||
|
||||
local maneuvers =
|
||||
{
|
||||
xi.effect.FIRE_MANEUVER,
|
||||
xi.effect.ICE_MANEUVER,
|
||||
xi.effect.WIND_MANEUVER,
|
||||
xi.effect.EARTH_MANEUVER,
|
||||
xi.effect.THUNDER_MANEUVER,
|
||||
xi.effect.WATER_MANEUVER,
|
||||
xi.effect.LIGHT_MANEUVER,
|
||||
xi.effect.DARK_MANEUVER,
|
||||
}
|
||||
|
||||
local removables =
|
||||
{
|
||||
-- Songs
|
||||
xi.effect.ELEGY,
|
||||
xi.effect.REQUIEM,
|
||||
xi.effect.THRENODY,
|
||||
|
||||
-- Enfeebling
|
||||
xi.effect.BLINDNESS,
|
||||
xi.effect.PARALYSIS,
|
||||
xi.effect.SILENCE,
|
||||
xi.effect.POISON,
|
||||
xi.effect.CURSE_I,
|
||||
xi.effect.CURSE_II,
|
||||
xi.effect.DISEASE,
|
||||
xi.effect.PLAGUE,
|
||||
xi.effect.WEIGHT,
|
||||
xi.effect.BIND,
|
||||
xi.effect.ADDLE,
|
||||
xi.effect.SLOW,
|
||||
xi.effect.PETRIFICATION,
|
||||
|
||||
-- DoTs
|
||||
xi.effect.BIO,
|
||||
xi.effect.DIA,
|
||||
xi.effect.BURN,
|
||||
xi.effect.FROST,
|
||||
xi.effect.CHOKE,
|
||||
xi.effect.RASP,
|
||||
xi.effect.SHOCK,
|
||||
xi.effect.DROWN,
|
||||
|
||||
-- Main Stat Downs
|
||||
xi.effect.STR_DOWN,
|
||||
xi.effect.DEX_DOWN,
|
||||
xi.effect.VIT_DOWN,
|
||||
xi.effect.AGI_DOWN,
|
||||
xi.effect.INT_DOWN,
|
||||
xi.effect.MND_DOWN,
|
||||
xi.effect.CHR_DOWN,
|
||||
|
||||
-- Combat Stat Downs
|
||||
xi.effect.ACCURACY_DOWN,
|
||||
xi.effect.ATTACK_DOWN,
|
||||
xi.effect.EVASION_DOWN,
|
||||
xi.effect.DEFENSE_DOWN,
|
||||
|
||||
-- Magic Stat Downs
|
||||
xi.effect.MAGIC_ACC_DOWN,
|
||||
xi.effect.MAGIC_ATK_DOWN,
|
||||
xi.effect.MAGIC_EVASION_DOWN,
|
||||
xi.effect.MAGIC_DEF_DOWN,
|
||||
|
||||
-- HP/MP/TP Stat Downs
|
||||
xi.effect.MAX_TP_DOWN,
|
||||
xi.effect.MAX_MP_DOWN,
|
||||
xi.effect.MAX_HP_DOWN,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.eraser.onAutomatonAbilityCheck', function(target, automaton, skill)
|
||||
return 0
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.eraser.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
automaton:addRecast(xi.recast.ABILITY, skill:getID(), 30)
|
||||
|
||||
local lightManeuvers = master:countEffect(xi.effect.LIGHT_MANEUVER)
|
||||
local effectsRemoved = 0
|
||||
|
||||
for _, effectId in ipairs(removables) do
|
||||
if target:hasStatusEffect(effectId) then
|
||||
target:delStatusEffectSilent(effectId)
|
||||
effectsRemoved = effectsRemoved + 1
|
||||
|
||||
if effectsRemoved >= lightManeuvers then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, maneuverId in ipairs(maneuvers) do
|
||||
for _ = 1, master:countEffect(maneuverId) do
|
||||
master:delStatusEffectSilent(maneuverId)
|
||||
end
|
||||
end
|
||||
|
||||
if effectsRemoved > 0 then
|
||||
skill:setMsg(xi.msg.basic.DISAPPEAR_NUM)
|
||||
else
|
||||
skill:setMsg(xi.msg.basic.USES)
|
||||
end
|
||||
|
||||
return effectsRemoved
|
||||
end)
|
||||
|
||||
return m
|
||||
45
modules/abyssea/lua/puppetmaster/replicator.lua
Normal file
45
modules/abyssea/lua/puppetmaster/replicator.lua
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
-----------------------------------
|
||||
-- Replicator (Pre-2011)
|
||||
-- Description : Applies Blink based on Wind Maneuvers when HP is below a certain threshold. Cooldown of 1 minute. Consumes all Wind Maneuvers on use.
|
||||
-- If Automaton has a Damage Gauge equipped, activation threshold is increased to 75% HP.
|
||||
-- Amount of images increased on December 15th, 2011.
|
||||
-- Changed from Blink to Copy Image on August 5th, 2015.
|
||||
-- Changed to not consume Wind Maneuvers on August 6th, 2019.
|
||||
-- https://wiki.ffo.jp/html/12225.html
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local m = Module:new('era_replicator')
|
||||
|
||||
local shadowTable =
|
||||
{
|
||||
[1] = 2,
|
||||
[2] = 3,
|
||||
[3] = 4,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.replicator.onAutomatonAbilityCheck', function(target, automaton, skill)
|
||||
return 0
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.replicator.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local windManeuvers = master:countEffect(xi.effect.WIND_MANEUVER)
|
||||
local shadows = shadowTable[windManeuvers]
|
||||
|
||||
automaton:addRecast(xi.recast.ABILITY, skill:getID(), 60)
|
||||
|
||||
for i = 1, windManeuvers do
|
||||
master:delStatusEffectSilent(xi.effect.WIND_MANEUVER)
|
||||
end
|
||||
|
||||
if target:addStatusEffect(xi.effect.BLINK, { power = shadows, duration = 300, origin = automaton }) then
|
||||
skill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT)
|
||||
else
|
||||
skill:setMsg(xi.msg.basic.SKILL_NO_EFFECT)
|
||||
end
|
||||
|
||||
return xi.effect.BLINK
|
||||
end)
|
||||
|
||||
return m
|
||||
|
|
@ -7,13 +7,7 @@
|
|||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local moduleName = 'unlocking_a_myth'
|
||||
|
||||
if xi.module.isContentEnabled('ABYSSEA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
local m = Module:new('unlocking_a_myth')
|
||||
|
||||
local weaponList =
|
||||
{
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
-----------------------------------
|
||||
-- NIN/DRG/SAM Quest Mobs Original Difficulty Module
|
||||
-- Reverts the nerfs to the NIN/DRG/SAM quest mobs in the May 10, 2011 version update
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/7257
|
||||
-----------------------------------
|
||||
|
||||
-- Level: set all six spawns to level 32 (min == max => fixed level)
|
||||
UPDATE mob_spawn_points SET minLevel = 32, maxLevel = 32 WHERE mobid = 17486187; -- Korroloka Leech (Korroloka Tunnel)
|
||||
UPDATE mob_spawn_points SET minLevel = 32, maxLevel = 32 WHERE mobid = 17486188; -- Korroloka Leech (Korroloka Tunnel)
|
||||
UPDATE mob_spawn_points SET minLevel = 32, maxLevel = 32 WHERE mobid = 17486189; -- Korroloka Leech (Korroloka Tunnel)
|
||||
UPDATE mob_spawn_points SET minLevel = 32, maxLevel = 32 WHERE mobid = 17350928; -- Cyranuce M Cutauleon (Ghelsba Outpost)
|
||||
UPDATE mob_spawn_points SET minLevel = 32, maxLevel = 32 WHERE mobid = 17219999; -- Forger (Konschtat Highlands)
|
||||
UPDATE mob_spawn_points SET minLevel = 32, maxLevel = 32 WHERE mobid = 17272838; -- Guardian Treant (The Sanctuary of Zi'Tah)
|
||||
|
||||
-- HP: per-group override, keyed by (groupid, zoneid)
|
||||
UPDATE mob_groups SET HP = 900 WHERE groupid = 28 AND zoneid = 173; -- Korroloka Leech x3 (Korroloka Tunnel)
|
||||
UPDATE mob_groups SET HP = 2700 WHERE groupid = 26 AND zoneid = 140; -- Cyranuce M Cutauleon (Ghelsba Outpost)
|
||||
UPDATE mob_groups SET HP = 2000 WHERE groupid = 33 AND zoneid = 108; -- Forger (Konschtat Highlands)
|
||||
UPDATE mob_groups SET HP = 2000 WHERE groupid = 5 AND zoneid = 121; -- Guardian Treant (The Sanctuary of Zi'Tah)
|
||||
|
|
@ -32,12 +32,28 @@ UPDATE merits SET value = 150 WHERE name = 'martyr';
|
|||
UPDATE merits SET value = 150 WHERE name = 'devotion';
|
||||
|
||||
-- Animus Solace: Disable merit upgrades
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/55360?_ga=2.195400239.203489549.1557463710-808700183.1440009048
|
||||
UPDATE merits SET upgrade = 0 WHERE name = 'animus_solace';
|
||||
|
||||
-- Animus Misery: Disable merit upgrades
|
||||
UPDATE merits SET upgrade = 0 WHERE name = 'animus_misery';
|
||||
|
||||
------------------------------------
|
||||
-- WHM Spell Cast Times
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
------------------------------------
|
||||
|
||||
-- Esuna: Revert cast time from 1 to 3 seconds
|
||||
UPDATE spell_list SET castTime = 3000 WHERE name = 'esuna';
|
||||
|
||||
-- Sacrifice: Revert cast time from 1 to 1.5 seconds
|
||||
UPDATE spell_list SET castTime = 1500 WHERE name = 'sacrifice';
|
||||
|
||||
-- Blindna: Revert cast time from 1 to 3 seconds
|
||||
UPDATE spell_list SET castTime = 3000 WHERE name = 'blindna';
|
||||
|
||||
-- Cursna: Revert cast time from 1 to 3 seconds
|
||||
UPDATE spell_list SET castTime = 3000 WHERE name = 'cursna';
|
||||
|
||||
------------------------------------
|
||||
-- Thief
|
||||
------------------------------------
|
||||
|
|
@ -69,8 +85,7 @@ UPDATE merits SET value = 20 WHERE name = 'arcane_circle_recast';
|
|||
UPDATE abilities SET recastTime = 300 WHERE name = 'weapon_bash';
|
||||
|
||||
-- Weapon Bash merit: Revert value to 10 seconds per level
|
||||
-- Note: merit is named weapon_bash_effect (provides both recast reduction and effect)
|
||||
UPDATE merits SET value = 10 WHERE name = 'weapon_bash_effect';
|
||||
UPDATE merits SET value = 10 WHERE name = 'weapon_bash_recast';
|
||||
|
||||
-- Dark Seal: Revert recast from 5 to 15 minutes
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012)
|
||||
|
|
@ -85,35 +100,6 @@ UPDATE abilities SET recastTime = 900 WHERE name = 'diabolic_eye';
|
|||
-- Diabolic Eye merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'diabolic_eye';
|
||||
|
||||
------------------------------------
|
||||
-- Paladin
|
||||
------------------------------------
|
||||
|
||||
-- Holy Circle: Revert recast from 5 to 10 minutes
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
UPDATE abilities SET recastTime = 600 WHERE name = 'holy_circle';
|
||||
|
||||
-- Holy Circle merit: Revert value to 20 seconds per level
|
||||
UPDATE merits SET value = 20 WHERE name = 'holy_circle_recast';
|
||||
|
||||
-- Chivalry: Revert recast from 10 to 20 minutes
|
||||
UPDATE abilities SET recastTime = 1200 WHERE name = 'chivalry';
|
||||
|
||||
-- Fealty: Revert recast from 10 to 20 minutes
|
||||
UPDATE abilities SET recastTime = 1200 WHERE name = 'fealty';
|
||||
|
||||
-- Chivalry merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'chivalry';
|
||||
|
||||
-- Fealty merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'fealty';
|
||||
|
||||
-- Shield Bash: Revert recast from 3 to 5 minutes
|
||||
UPDATE abilities SET recastTime = 300 WHERE name = 'shield_bash';
|
||||
|
||||
-- Shield Bash merit: Revert value to 10 seconds per level
|
||||
UPDATE merits SET value = 10 WHERE name = 'shield_bash_recast';
|
||||
|
||||
------------------------------------
|
||||
-- Beastmaster
|
||||
------------------------------------
|
||||
|
|
@ -139,25 +125,6 @@ UPDATE abilities SET recastTime = 900 WHERE name = 'killer_instinct';
|
|||
-- Killer Instinct merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'killer_instinct';
|
||||
|
||||
------------------------------------
|
||||
-- Bard
|
||||
------------------------------------
|
||||
|
||||
-- Mazurka: Revert to town/field only
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(09/08/2010)
|
||||
SET @TYPE_CITY = 1;
|
||||
SET @TYPE_OUTDOORS = 2;
|
||||
SET @MISC_MAZURKA = 8;
|
||||
|
||||
-- Remove mazurka from all zones
|
||||
UPDATE zone_settings
|
||||
SET misc = misc & ~@MISC_MAZURKA;
|
||||
|
||||
-- Reapply to cities and outdoor zones
|
||||
UPDATE zone_settings
|
||||
SET misc = misc | @MISC_MAZURKA
|
||||
WHERE (zonetype & (@TYPE_CITY | @TYPE_OUTDOORS)) <> 0;
|
||||
|
||||
------------------------------------
|
||||
-- Samurai
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
|
|
@ -214,6 +181,13 @@ UPDATE abilities SET recastTime = 300 WHERE name = 'yonin';
|
|||
-- Innin: Revert recast from 3 minutes to 5 minutes and add shared cooldown with Yonin
|
||||
UPDATE abilities SET recastTime = 300, recastId = 146 WHERE name = 'innin';
|
||||
|
||||
-- Tonko: Ichi: Revert cast time from 1.5 to 4 seconds
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
UPDATE spell_list SET castTime = 4000 WHERE name = 'tonko_ichi';
|
||||
|
||||
-- Monomi: Ichi: Revert cast time from 1.5 to 4 seconds
|
||||
UPDATE spell_list SET castTime = 4000 WHERE name = 'monomi_ichi';
|
||||
|
||||
-----------------------------------
|
||||
-- Dragoon
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
|
|
@ -251,35 +225,3 @@ UPDATE abilities SET recastTime = 900 WHERE name = 'deep_breathing';
|
|||
|
||||
-- Deep Breathing merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'deep_breathing';
|
||||
|
||||
-----------------------------------
|
||||
-- Summoner
|
||||
-----------------------------------
|
||||
|
||||
-- Summoning Magic Casting Time Merit: Repurposed to Spirit MP cost merit. Revert merit value from 5 to 1 per level.
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/22099-March-27-2012-%28JST%29-Version-Update
|
||||
UPDATE merits SET value = 1 WHERE name = 'summoning_magic_cast_time';
|
||||
|
||||
-----------------------------------
|
||||
-- Corsair
|
||||
-----------------------------------
|
||||
|
||||
-- Double-Up: Revert recast from 5 to 7 seconds
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(09/19/2011)
|
||||
UPDATE abilities SET recastTime = 7 WHERE name = 'double-up';
|
||||
|
||||
-- Snake Eye: Revert recast from 5 to 15 minutes
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(05/15/2012)
|
||||
UPDATE abilities SET recastTime = 900 WHERE name = 'snake_eye';
|
||||
|
||||
-- Snake Eye merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'snake_eye';
|
||||
|
||||
-- Fold: Revert recast from 5 to 15 minutes
|
||||
UPDATE abilities SET recastTime = 900 WHERE name = 'fold';
|
||||
|
||||
-- Fold merit: Revert value to 150 seconds per level
|
||||
UPDATE merits SET value = 150 WHERE name = 'fold';
|
||||
|
||||
-- Quick Draw: Revert range from 22 to 15 yalms
|
||||
UPDATE abilities SET `range` = 15 WHERE name = 'quick_draw';
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
------------------------------------
|
||||
-- Abyssea Spell SQL Adjustments
|
||||
-- This module reverts relevant spells to their pre-Abyssea values
|
||||
------------------------------------
|
||||
|
||||
------------------------------------
|
||||
-- Healing Magic
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
------------------------------------
|
||||
|
||||
-- Esuna: Revert cast time from 1 to 3 seconds
|
||||
UPDATE spell_list SET castTime = 3000 WHERE name = 'esuna';
|
||||
|
||||
-- Sacrifice: Revert cast time from 1 to 1.5 seconds
|
||||
UPDATE spell_list SET castTime = 1500 WHERE name = 'sacrifice';
|
||||
|
||||
-- Blindna: Revert cast time from 1 to 3 seconds
|
||||
UPDATE spell_list SET castTime = 3000 WHERE name = 'blindna';
|
||||
|
||||
-- Cursna: Revert cast time from 1 to 3 seconds
|
||||
UPDATE spell_list SET castTime = 3000 WHERE name = 'cursna';
|
||||
|
||||
------------------------------------
|
||||
-- Enhancing Magic
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(12/14/2011)
|
||||
------------------------------------
|
||||
|
||||
-- Regen: Revert cast time from 1.5 to 4 seconds
|
||||
UPDATE spell_list SET castTime = 4000 WHERE name = 'regen';
|
||||
|
||||
-- Regen II: Revert cast time from 1.75 to 4.5 seconds
|
||||
UPDATE spell_list SET castTime = 4500 WHERE name = 'regen_ii';
|
||||
|
||||
-- Regen III: Revert cast time from 2 to 5 seconds
|
||||
UPDATE spell_list SET castTime = 5000 WHERE name = 'regen_iii';
|
||||
|
||||
------------------------------------
|
||||
-- Singing
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/29150-December-13-2012-%28JST%29-Version-Update
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/27883-dev1138-Bard-Job-Adjustments
|
||||
------------------------------------
|
||||
|
||||
-- Etudes / Prelude / Sirvente / Dirge: Revert from AoE to single target and cast time to 4 seconds
|
||||
UPDATE spell_list SET validTargets = 3, AOE = 0, castTime = 4000 WHERE name IN (
|
||||
'foe_sirvente',
|
||||
'adventurers_dirge',
|
||||
'hunters_prelude',
|
||||
'archers_prelude',
|
||||
'sinewy_etude',
|
||||
'dextrous_etude',
|
||||
'vivacious_etude',
|
||||
'quick_etude',
|
||||
'learned_etude',
|
||||
'spirited_etude',
|
||||
'enchanting_etude',
|
||||
'herculean_etude',
|
||||
'uncanny_etude',
|
||||
'vital_etude',
|
||||
'swift_etude',
|
||||
'sage_etude',
|
||||
'logical_etude',
|
||||
'bewitching_etude'
|
||||
);
|
||||
|
||||
------------------------------------
|
||||
-- Ninjutsu
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012)
|
||||
------------------------------------
|
||||
|
||||
-- Tonko: Ichi: Revert cast time from 1.5 to 4 seconds
|
||||
UPDATE spell_list SET castTime = 4000 WHERE name = 'tonko_ichi';
|
||||
|
||||
-- Monomi: Ichi: Revert cast time from 1.5 to 4 seconds
|
||||
UPDATE spell_list SET castTime = 4000 WHERE name = 'monomi_ichi';
|
||||
|
|
@ -7,13 +7,7 @@
|
|||
require('modules/module_utils')
|
||||
require('scripts/globals/treasure')
|
||||
-----------------------------------
|
||||
local moduleName = 'pre_rmt_drops'
|
||||
|
||||
if xi.module.isContentEnabled('COP') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
return { name = moduleName }
|
||||
local m = Module:new('pre_rmt_drops')
|
||||
|
||||
--[[
|
||||
-- This Module is disabled until the new treasure system is tested an appropiate amount of time.
|
||||
|
|
@ -34,3 +28,5 @@ m:addOverride('xi.zones.Castle_Oztroja.Zone.onInitialize', function(zone)
|
|||
|
||||
end)
|
||||
]]--
|
||||
|
||||
return m
|
||||
|
|
@ -45,7 +45,7 @@ class AHPaginationModule : public CPPModule
|
|||
return false;
|
||||
}
|
||||
|
||||
if (PChar->m_GMlevel == 0 && !PChar->loc.zone->CanUseMisc(xi::ZoneMisc::AuctionHouse))
|
||||
if (PChar->m_GMlevel == 0 && !PChar->loc.zone->CanUseMisc(MISC_AH))
|
||||
{
|
||||
ShowWarning("[AH PAGES] %s is trying to use the auction house in a disallowed zone [%s]", PChar->getName(), PChar->loc.zone->getName());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.Zone.onInitialize', function(zone)
|
|||
|
||||
-- First-time setup.
|
||||
if hnmPopTime == 0 then
|
||||
hnmPopTime = currentTime + math.randomInt(1, 48) * 1800
|
||||
hnmPopTime = currentTime + math.random(1, 48) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Fafnir', hnmPopTime) -- Save pop time.
|
||||
end
|
||||
|
|
@ -54,7 +54,7 @@ hnmSystem:addOverride('xi.zones.Dragons_Aery.mobs.Fafnir.onMobDespawn', function
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Fafnir', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.Zone.onInitialize', function(z
|
|||
|
||||
-- First-time setup.
|
||||
if hnmPopTime == 0 then
|
||||
hnmPopTime = currentTime + math.randomInt(1, 48) * 1800
|
||||
hnmPopTime = currentTime + math.random(1, 48) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Adamantoise', hnmPopTime) -- Save pop time.
|
||||
end
|
||||
|
|
@ -104,7 +104,7 @@ hnmSystem:addOverride('xi.zones.Valley_of_Sorrows.mobs.Adamantoise.onMobDespawn'
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Adamantoise', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.Zone.onInitialize', function(
|
|||
|
||||
-- First-time setup.
|
||||
if hnmPopTime == 0 then
|
||||
hnmPopTime = currentTime + math.randomInt(1, 48) * 1800
|
||||
hnmPopTime = currentTime + math.random(1, 48) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Behemoth', hnmPopTime) -- Save pop time.
|
||||
end
|
||||
|
|
@ -154,7 +154,7 @@ hnmSystem:addOverride('xi.zones.Behemoths_Dominion.mobs.Behemoth.onMobDespawn',
|
|||
super(mob)
|
||||
|
||||
-- Server Variable work.
|
||||
local randomPopTime = 75600 + math.randomInt(0, 6) * 1800
|
||||
local randomPopTime = 75600 + math.random(0, 6) * 1800
|
||||
|
||||
SetServerVariable('[HNM]Behemoth', GetSystemTime() + randomPopTime) -- Save next pop time.
|
||||
|
||||
|
|
|
|||
20
modules/custom/lua/missable_mom_the_adventurer.lua
Normal file
20
modules/custom/lua/missable_mom_the_adventurer.lua
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
-----------------------------------
|
||||
-- Module to make 'Mom the Adventurer?' quest missable.
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local m = Module:new('missable_mom_the_adventurer')
|
||||
|
||||
m:addOverride('xi.server.onServerStart', function()
|
||||
super()
|
||||
|
||||
xi.module.modifyInteractionEntry('scripts/quests/bastok/Mom_the_Adventurer', function(quest)
|
||||
quest.sections[1].check = function(player, status, vars)
|
||||
return status ~= xi.questStatus.QUEST_ACCEPTED and
|
||||
player:getFameLevel(xi.fameArea.BASTOK) < 2 and
|
||||
vars.Prog == 0
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
return m
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Mog House Exit Home Point Prompt Module
|
||||
-----------------------------------
|
||||
-- Restores the prompt to set your home point when exiting the Mog House after changing jobs.
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
require('scripts/globals/moghouse')
|
||||
-----------------------------------
|
||||
local m = Module:new('moghouse_exit_homepoint')
|
||||
|
||||
-- Variable used for this module to store the job snapshot in the player's character variables.
|
||||
local jobSnapshot = 'moghouseExitJobSnapshot'
|
||||
|
||||
-- The current event ID for the Mog House exit prompt. May change with future updates. If this module ever breaks, check here first.
|
||||
local exitEventId = 30004
|
||||
|
||||
-- Zones to prompt players to set their home point upon exiting the Mog House.
|
||||
local exitZones =
|
||||
{
|
||||
['Southern_San_dOria' ] = xi.zone.SOUTHERN_SAN_DORIA,
|
||||
['Northern_San_dOria' ] = xi.zone.NORTHERN_SAN_DORIA,
|
||||
['Port_San_dOria' ] = xi.zone.PORT_SAN_DORIA,
|
||||
['Bastok_Mines' ] = xi.zone.BASTOK_MINES,
|
||||
['Bastok_Markets' ] = xi.zone.BASTOK_MARKETS,
|
||||
['Port_Bastok' ] = xi.zone.PORT_BASTOK,
|
||||
['Windurst_Waters' ] = xi.zone.WINDURST_WATERS,
|
||||
['Windurst_Walls' ] = xi.zone.WINDURST_WALLS,
|
||||
['Port_Windurst' ] = xi.zone.PORT_WINDURST,
|
||||
['Windurst_Woods' ] = xi.zone.WINDURST_WOODS,
|
||||
['RuLude_Gardens' ] = xi.zone.RULUDE_GARDENS,
|
||||
['Upper_Jeuno' ] = xi.zone.UPPER_JEUNO,
|
||||
['Lower_Jeuno' ] = xi.zone.LOWER_JEUNO,
|
||||
['Port_Jeuno' ] = xi.zone.PORT_JEUNO,
|
||||
['Al_Zahbi' ] = xi.zone.AL_ZAHBI,
|
||||
['Aht_Urhgan_Whitegate' ] = xi.zone.AHT_URHGAN_WHITEGATE,
|
||||
['Southern_San_dOria_[S]'] = xi.zone.SOUTHERN_SAN_DORIA_S,
|
||||
['Bastok_Markets_[S]' ] = xi.zone.BASTOK_MARKETS_S,
|
||||
['Windurst_Waters_[S]' ] = xi.zone.WINDURST_WATERS_S,
|
||||
}
|
||||
|
||||
local promptZoneIds = {}
|
||||
for _, zoneId in pairs(exitZones) do
|
||||
promptZoneIds[zoneId] = true
|
||||
end
|
||||
|
||||
local currentJob = function(player)
|
||||
return player:getMainJob() * 100 + player:getSubJob()
|
||||
end
|
||||
|
||||
m:addOverride('xi.moghouse.onMoghouseZoneEvent', function(player, prevZone)
|
||||
-- Create a snapshot of the players current job when entering the mog house.
|
||||
if player:inMogHouse() then
|
||||
player:setCharVar(jobSnapshot, currentJob(player))
|
||||
|
||||
return super(player, prevZone)
|
||||
end
|
||||
|
||||
local moghouseExitPos = player:getXPos() == 0 and player:getYPos() == 0 and player:getZPos() == 0
|
||||
local baseCsId = super(player, prevZone)
|
||||
local storedJob = player:getCharVar(jobSnapshot)
|
||||
|
||||
if moghouseExitPos and storedJob > 0 then
|
||||
player:setCharVar(jobSnapshot, 0)
|
||||
|
||||
if
|
||||
baseCsId == -1 and
|
||||
promptZoneIds[player:getZoneID()] and
|
||||
storedJob ~= currentJob(player)
|
||||
then
|
||||
return exitEventId
|
||||
end
|
||||
end
|
||||
|
||||
return baseCsId
|
||||
end)
|
||||
|
||||
for zoneName in pairs(exitZones) do
|
||||
m:addOverride(string.format('xi.zones.%s.Zone.onEventFinish', zoneName), function(player, csid, option, npc)
|
||||
if csid == exitEventId then
|
||||
if option == 0 then
|
||||
player:setHomePoint()
|
||||
player:messageSpecial(zones[player:getZoneID()].text.HOMEPOINT_SET)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
super(player, csid, option, npc)
|
||||
end)
|
||||
end
|
||||
|
||||
return m
|
||||
|
|
@ -20,7 +20,7 @@ local nmsToPersist =
|
|||
'Behemoths_Dominion',
|
||||
'Behemoth',
|
||||
function()
|
||||
return 75600 + math.randomInt(0, 6) * 1800
|
||||
return 75600 + math.random(0, 6) * 1800
|
||||
end
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,297 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Reverts blood pacts to no longer have a duration based on summoning magic.
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(09/08/2010)
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local moduleName = 'abyssea_avatar_bloodpacts'
|
||||
|
||||
if xi.module.isContentEnabled('ABYSSEA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
-----------------------------------
|
||||
-- Shining Ruby
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.shining_ruby.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
target:delStatusEffect(xi.effect.SHINING_RUBY)
|
||||
target:addStatusEffect(xi.effect.SHINING_RUBY, { power = 1, duration = duration, origin = pet })
|
||||
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
|
||||
return xi.effect.SHINING_RUBY
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Hastega
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.hastega.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
-- Reverts Garuda's Hastega to use 102/1024 or 9.96%
|
||||
local typeEffect = xi.effect.HASTE
|
||||
if target:addStatusEffect(typeEffect, { power = 996, duration = duration, origin = pet }) then
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2)
|
||||
return
|
||||
end
|
||||
|
||||
return typeEffect
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Crimson Howl
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.crimson_howl.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 60
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local typeEffect = xi.effect.WARCRY
|
||||
if target:addStatusEffect(typeEffect, { power = 9, duration = duration, origin = pet }) then
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2)
|
||||
return
|
||||
end
|
||||
|
||||
return typeEffect
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Frost Armor
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.frost_armor.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local typeEffect = xi.effect.ICE_SPIKES
|
||||
target:delStatusEffect(typeEffect)
|
||||
|
||||
if target:addStatusEffect(typeEffect, { power = 15, duration = duration, origin = pet }) then
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2)
|
||||
return
|
||||
end
|
||||
|
||||
return typeEffect
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Rolling Thunder
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.rolling_thunder.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 120
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local magicskill = xi.data.skillLevel.getSkillCap(target:getMainLvl(), xi.skillRank.A_PLUS)
|
||||
local potency = 3 + 6 * magicskill / 100
|
||||
|
||||
if magicskill > 200 then
|
||||
potency = 5 + 5 * magicskill / 100
|
||||
end
|
||||
|
||||
xi.mobskills.mobBuffMove(target, xi.effect.ENTHUNDER, potency, 0, duration)
|
||||
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.JA_RECEIVES_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_RECEIVES_EFFECT)
|
||||
end
|
||||
|
||||
return xi.effect.ENTHUNDER
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Lightning Armor
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.lightning_armor.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local typeEffect = xi.effect.SHOCK_SPIKES
|
||||
target:delStatusEffect(typeEffect)
|
||||
|
||||
if target:addStatusEffect(typeEffect, { power = 15, duration = duration, origin = pet }) then
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2)
|
||||
return
|
||||
end
|
||||
|
||||
return typeEffect
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Ecliptic Growl
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.ecliptic_growl.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local moonCycle = getVanadielMoonCycle()
|
||||
|
||||
local cycleBuffs =
|
||||
{
|
||||
[xi.moonCycle.NEW_MOON] = 1,
|
||||
[xi.moonCycle.LESSER_WAXING_CRESCENT] = 2,
|
||||
[xi.moonCycle.GREATER_WAXING_CRESCENT] = 3,
|
||||
[xi.moonCycle.FIRST_QUARTER] = 4,
|
||||
[xi.moonCycle.LESSER_WAXING_GIBBOUS] = 5,
|
||||
[xi.moonCycle.GREATER_WAXING_GIBBOUS] = 6,
|
||||
[xi.moonCycle.FULL_MOON] = 7,
|
||||
[xi.moonCycle.GREATER_WANING_GIBBOUS] = 6,
|
||||
[xi.moonCycle.LESSER_WANING_GIBBOUS] = 5,
|
||||
[xi.moonCycle.THIRD_QUARTER] = 4,
|
||||
[xi.moonCycle.GREATER_WANING_CRESCENT] = 3,
|
||||
[xi.moonCycle.LESSER_WANING_CRESCENT] = 2,
|
||||
}
|
||||
|
||||
local buffValue = cycleBuffs[moonCycle]
|
||||
|
||||
target:delStatusEffect(xi.effect.STR_BOOST)
|
||||
target:delStatusEffect(xi.effect.DEX_BOOST)
|
||||
target:delStatusEffect(xi.effect.VIT_BOOST)
|
||||
target:delStatusEffect(xi.effect.AGI_BOOST)
|
||||
target:delStatusEffect(xi.effect.MND_BOOST)
|
||||
target:delStatusEffect(xi.effect.CHR_BOOST)
|
||||
|
||||
target:addStatusEffect(xi.effect.STR_BOOST, { power = buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.DEX_BOOST, { power = buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.VIT_BOOST, { power = buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.AGI_BOOST, { power = 8 - buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.INT_BOOST, { power = 8 - buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.MND_BOOST, { power = 8 - buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.CHR_BOOST, { power = 8 - buffValue, duration = duration, origin = pet })
|
||||
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.STATUS_BOOST)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.STATUS_BOOST_2)
|
||||
end
|
||||
|
||||
return 0
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Ecliptic Howl
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.ecliptic_howl.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local moonCycle = getVanadielMoonCycle()
|
||||
|
||||
local cycleBuffs =
|
||||
{
|
||||
[xi.moonCycle.NEW_MOON] = 1,
|
||||
[xi.moonCycle.LESSER_WAXING_CRESCENT] = 5,
|
||||
[xi.moonCycle.GREATER_WAXING_CRESCENT] = 9,
|
||||
[xi.moonCycle.FIRST_QUARTER] = 13,
|
||||
[xi.moonCycle.LESSER_WAXING_GIBBOUS] = 17,
|
||||
[xi.moonCycle.GREATER_WAXING_GIBBOUS] = 21,
|
||||
[xi.moonCycle.FULL_MOON] = 25,
|
||||
[xi.moonCycle.GREATER_WANING_GIBBOUS] = 21,
|
||||
[xi.moonCycle.LESSER_WANING_GIBBOUS] = 17,
|
||||
[xi.moonCycle.THIRD_QUARTER] = 13,
|
||||
[xi.moonCycle.GREATER_WANING_CRESCENT] = 9,
|
||||
[xi.moonCycle.LESSER_WANING_CRESCENT] = 5,
|
||||
}
|
||||
|
||||
local buffValue = cycleBuffs[moonCycle]
|
||||
|
||||
target:delStatusEffect(xi.effect.ACCURACY_BOOST)
|
||||
target:delStatusEffect(xi.effect.EVASION_BOOST)
|
||||
target:addStatusEffect(xi.effect.ACCURACY_BOOST, { power = buffValue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.EVASION_BOOST, { power = 25 - buffValue, duration = duration, origin = pet })
|
||||
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.ACC_EVA_BOOST)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.ACC_EVA_BOOST_2)
|
||||
end
|
||||
|
||||
return 0
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Noctoshield
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.noctoshield.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
if target:addStatusEffect(xi.effect.PHALANX, { power = 13, duration = duration, origin = pet }) then
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2)
|
||||
return
|
||||
end
|
||||
|
||||
return xi.effect.PHALANX
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Dream Shroud
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.dream_shroud.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
local duration = 180
|
||||
local hour = VanadielHour()
|
||||
local buffvalue = math.abs(12 - hour) + 1
|
||||
|
||||
target:delStatusEffect(xi.effect.MAGIC_ATK_BOOST)
|
||||
target:delStatusEffect(xi.effect.MAGIC_DEF_BOOST)
|
||||
target:addStatusEffect(xi.effect.MAGIC_ATK_BOOST, { power = buffvalue, duration = duration, origin = pet })
|
||||
target:addStatusEffect(xi.effect.MAGIC_DEF_BOOST, { power = 14 - buffvalue, duration = duration, origin = pet })
|
||||
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.JA_RECEIVES_MAB_MDB)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_RECEIVES_MAB_MDB_2)
|
||||
end
|
||||
|
||||
return 0
|
||||
end)
|
||||
|
||||
return m
|
||||
|
|
@ -1,552 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Attachment module
|
||||
-- Recreates attachment effects in the WoTG Era.
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
require('scripts/globals/automaton')
|
||||
-----------------------------------
|
||||
|
||||
local moduleName = 'attachments'
|
||||
|
||||
if xi.module.isContentEnabled('ABYSSEA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
-- Reduces Enmity boost from Strobe : https://wiki.ffo.jp/html/8610.html
|
||||
-- Reduces Store TP from Inhibitor : https://wiki.ffo.jp/html/8625.html
|
||||
-- Changes Armor Plate and Armor Plate II to Defense instead of PDT : https://wiki.ffo.jp/html/9070.html
|
||||
-- Adds a Ranged Attack Penalty to Drum Magazine. : https://wiki.ffo.jp/html/8882.html
|
||||
-- Changes Turbo Charger Haste to Gear Haste instead of Magic : https://wiki.ffo.jp/html/8627.html
|
||||
-- Adds Burden to Tactical Processor : https://wiki.ffo.jp/html/13527.html
|
||||
-- Reduces scaling from Volt Gun : https://wiki.ffo.jp/html/8752.html
|
||||
-- Reduces Burden Decay From Heatsink : https://wiki.ffo.jp/html/8629.html
|
||||
-- Reduces the potency of Steam Jackets Damage Reduction : https://wiki.ffo.jp/html/15352.html
|
||||
xi.automaton.attachmentModifiers['strobe' ] = { { modifier = xi.mod.ENMITY, values = { 5, 15, 25, 40 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['inhibitor' ] = { { modifier = xi.mod.STORETP, values = { 5, 10, 15, 20 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['armor_plate' ] = { { modifier = xi.mod.DEFP, values = { 10, 15, 20, 25 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['armor_plate_ii' ] = { { modifier = xi.mod.DEFP, values = { 20, 25, 30, 35 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['drum_magazine' ] = { { modifier = xi.mod.AUTO_RANGED_DELAY, values = { 2, 4, 6, 8 }, opticFiber = false },
|
||||
{ modifier = xi.mod.RACC, values = { -15, -30, -50, -75 }, opticFiber = false }, }
|
||||
xi.automaton.attachmentModifiers['flame_holder' ] = { { modifier = xi.mod.WEAPONSKILL_DAMAGE_BASE, values = { 0, 125, 150, 175 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['ice_maker' ] = { { modifier = xi.mod.AUTO_MAB_COEFFICIENT, values = { 0, 20, 40, 60 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['turbo_charger' ] = { { modifier = xi.mod.HASTE_GEAR, values = { 500, 1500, 2000, 2500 }, opticFiber = true }, }
|
||||
xi.automaton.attachmentModifiers['tactical_processor'] = { { modifier = xi.mod.AUTO_DECISION_DELAY, values = { 50, 70, 85, 115 }, opticFiber = false },
|
||||
{ modifier = xi.mod.OVERLOAD_THRESH, values = { -5, -5, -5, -5 }, opticFiber = false }, }
|
||||
xi.automaton.attachmentModifiers['volt_gun' ] = { { modifier = xi.mod.VOLT_GUN_POTENCY, values = { 0, 0, 0, 0 }, opticFiber = false }, }
|
||||
xi.automaton.attachmentModifiers['heatsink' ] = { { modifier = xi.mod.BURDEN_DECAY, values = { 1, 1, 1, 1 }, opticFiber = false }, }
|
||||
xi.automaton.attachmentModifiers['steam_jacket' ] = { { modifier = xi.mod.AUTO_STEAM_JACKET_REDUCTION, values = { 25, 35, 40, 60 }, opticFiber = true }, }
|
||||
|
||||
-- Reduces potency of Auto Repair Kit II and removed level based scaling from Mana Tank : https://wiki.ffo.jp/html/19739.html
|
||||
xi.automaton.repairKit.data['auto-repair_kit_ii' ] = { id = 196, hpBoost = 2, regenBase = { 0, 2, 3, 4 }, regenMultiplier = { 0, 0.4, 0.6, 0.8 } }
|
||||
xi.automaton.manaTank.data ['mana_tank' ] = { id = 225, mpBoost = 1, refreshBase = { 0, 1, 2, 3 }, refreshMultiplier = { 0, 0.0, 0.0, 0.0 } }
|
||||
xi.automaton.manaTank.data ['mana_tank_ii' ] = { id = 228, mpBoost = 2, refreshBase = { 0, 2, 3, 4 }, refreshMultiplier = { 0, 0.0, 0.0, 0.0 } }
|
||||
|
||||
-----------------------------------
|
||||
-- Flame Holder - Reduces Flame Holder Scaling, and consumes all Fire Maneuvers on weaponskill execution. https://wiki.ffo.jp/html/11183.html
|
||||
-----------------------------------
|
||||
local validFlameHolderSkills = set
|
||||
{
|
||||
xi.mobSkill.ARCUBALLISTA_AUTOMATON,
|
||||
xi.mobSkill.ARMOR_PIERCER_AUTOMATON,
|
||||
xi.mobSkill.ARMOR_SHATTERER_AUTOMATON,
|
||||
xi.mobSkill.BONE_CRUSHER_AUTOMATON,
|
||||
xi.mobSkill.CANNIBAL_BLADE_AUTOMATON,
|
||||
xi.mobSkill.CHIMERA_RIPPER_AUTOMATON,
|
||||
xi.mobSkill.DAZE_AUTOMATON,
|
||||
xi.mobSkill.KNOCKOUT_AUTOMATON,
|
||||
xi.mobSkill.MAGIC_MORTAR_AUTOMATON,
|
||||
xi.mobSkill.SLAPSTICK_AUTOMATON,
|
||||
xi.mobSkill.STRING_CLIPPER_AUTOMATON,
|
||||
xi.mobSkill.STRING_SHREDDER_AUTOMATON,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onEquip', function(pet, attachment)
|
||||
pet:addListener('WEAPONSKILL_STATE_EXIT', 'AUTO_FLAME_HOLDER_END', function(automaton, skillId, wasExecuted)
|
||||
if not validFlameHolderSkills[skillId] then
|
||||
return
|
||||
end
|
||||
|
||||
if not wasExecuted then
|
||||
return
|
||||
end
|
||||
|
||||
local master = automaton:getMaster()
|
||||
|
||||
if not master then
|
||||
return
|
||||
end
|
||||
|
||||
-- Consume all Fire Maneuvers on weaponskill execution.
|
||||
local fireManeuvers = master:countEffect(xi.effect.FIRE_MANEUVER)
|
||||
|
||||
for i = 1, fireManeuvers do
|
||||
master:delStatusEffectSilent(xi.effect.FIRE_MANEUVER)
|
||||
end
|
||||
|
||||
master:updateAttachments()
|
||||
end)
|
||||
|
||||
xi.automaton.onAttachmentEquip(pet, attachment)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onUnequip', function(pet, attachment)
|
||||
xi.automaton.onAttachmentUnequip(pet, attachment)
|
||||
pet:removeListener('AUTO_FLAME_HOLDER_END')
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Ice Maker - Reduces Magic Attack Bonus from Ice Maker, and consumes all Ice Maneuvers on magic attack execution. https://wiki.ffo.jp/html/11198.html
|
||||
-----------------------------------
|
||||
local validIceMakerSpells = set
|
||||
{
|
||||
xi.magic.spell.FIRE,
|
||||
xi.magic.spell.FIRE_II,
|
||||
xi.magic.spell.FIRE_III,
|
||||
xi.magic.spell.FIRE_IV,
|
||||
xi.magic.spell.FIRE_V,
|
||||
xi.magic.spell.BLIZZARD,
|
||||
xi.magic.spell.BLIZZARD_II,
|
||||
xi.magic.spell.BLIZZARD_III,
|
||||
xi.magic.spell.BLIZZARD_IV,
|
||||
xi.magic.spell.BLIZZARD_V,
|
||||
xi.magic.spell.AERO,
|
||||
xi.magic.spell.AERO_II,
|
||||
xi.magic.spell.AERO_III,
|
||||
xi.magic.spell.AERO_IV,
|
||||
xi.magic.spell.AERO_V,
|
||||
xi.magic.spell.STONE,
|
||||
xi.magic.spell.STONE_II,
|
||||
xi.magic.spell.STONE_III,
|
||||
xi.magic.spell.STONE_IV,
|
||||
xi.magic.spell.STONE_V,
|
||||
xi.magic.spell.THUNDER,
|
||||
xi.magic.spell.THUNDER_II,
|
||||
xi.magic.spell.THUNDER_III,
|
||||
xi.magic.spell.THUNDER_IV,
|
||||
xi.magic.spell.THUNDER_V,
|
||||
xi.magic.spell.WATER,
|
||||
xi.magic.spell.WATER_II,
|
||||
xi.magic.spell.WATER_III,
|
||||
xi.magic.spell.WATER_IV,
|
||||
xi.magic.spell.WATER_V,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.ice_maker.onEquip', function(pet, attachment)
|
||||
pet:addListener('MAGIC_USE', 'AUTO_ICE_MAKER_USE', function(automaton, target, spell, action)
|
||||
if not validIceMakerSpells[spell:getID()] then
|
||||
return
|
||||
end
|
||||
|
||||
local master = automaton:getMaster()
|
||||
|
||||
if not master then
|
||||
return
|
||||
end
|
||||
|
||||
local iceManeuvers = master:countEffect(xi.effect.ICE_MANEUVER)
|
||||
|
||||
for i = 1, iceManeuvers do
|
||||
master:delStatusEffectSilent(xi.effect.ICE_MANEUVER)
|
||||
end
|
||||
|
||||
master:updateAttachments()
|
||||
end)
|
||||
|
||||
xi.automaton.onAttachmentEquip(pet, attachment)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.ice_maker.onUnequip', function(pet, attachment)
|
||||
xi.automaton.onAttachmentUnequip(pet, attachment)
|
||||
pet:removeListener('AUTO_ICE_MAKER_USE')
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Replicator - Reduces amount of absorbs granted by Replicator, and changes them to Blink from Utsusemi. Also consumes Wind Maneuvers. https://wiki.ffo.jp/html/12225.html
|
||||
-----------------------------------
|
||||
local shadowTable =
|
||||
{
|
||||
[1] = 2,
|
||||
[2] = 3,
|
||||
[3] = 4,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.replicator.onAutomatonAbilityCheck', function(target, automaton, skill)
|
||||
return 0
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.replicator.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local windManeuvers = xi.automaton.getManeuverCount(master, master:countEffect(xi.effect.WIND_MANEUVER))
|
||||
local shadows = shadowTable[windManeuvers]
|
||||
|
||||
automaton:addRecast(xi.recast.ABILITY, skill:getID(), 60)
|
||||
|
||||
for i = 1, windManeuvers do
|
||||
master:delStatusEffectSilent(xi.effect.WIND_MANEUVER)
|
||||
end
|
||||
|
||||
master:updateAttachments()
|
||||
|
||||
if
|
||||
shadows and
|
||||
target:addStatusEffect(xi.effect.BLINK, { power = shadows, duration = 300, origin = automaton })
|
||||
then
|
||||
skill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT)
|
||||
else
|
||||
skill:setMsg(xi.msg.basic.SKILL_NO_EFFECT)
|
||||
end
|
||||
|
||||
return xi.effect.BLINK
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Shock Absorber - Reduces the potency of the stoneskin effect and removes scaling. https://wiki.ffo.jp/html/12927.html
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.shock_absorber.onAutomatonAbilityCheck', function(target, automaton, skill)
|
||||
return 0
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.shock_absorber.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
automaton:addRecast(xi.recast.ABILITY, skill:getID(), 180)
|
||||
|
||||
if target:addStatusEffect(xi.effect.STONESKIN, { power = 100, duration = 180, origin = automaton, tier = 4 }) then
|
||||
skill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT)
|
||||
else
|
||||
skill:setMsg(xi.msg.basic.SKILL_NO_EFFECT)
|
||||
end
|
||||
|
||||
return xi.effect.STONESKIN
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Shield Bash - Removes gaurunteed hit chance while Hammermill is equipped. https://wiki.ffo.jp/html/12156.html
|
||||
-----------------------------------
|
||||
local shieldBashSlowTable =
|
||||
{
|
||||
[1] = { tier = 4, duration = 30 },
|
||||
[2] = { tier = 5, duration = 50 },
|
||||
[3] = { tier = 6, duration = 70 },
|
||||
}
|
||||
|
||||
local function applyHammermillSlow(automaton, target, skill, master)
|
||||
local power = automaton:getMod(xi.mod.AUTO_SHIELD_BASH_SLOW) * 100
|
||||
if power <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local slowTier = shieldBashSlowTable[master and xi.automaton.getManeuverCount(master, master:countEffect(xi.effect.EARTH_MANEUVER)) or 0]
|
||||
|
||||
local params =
|
||||
{
|
||||
[1] = { effectId = xi.effect.SLOW, power = power, duration = slowTier.duration, tier = slowTier.tier },
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(automaton, target, skill, params, { messageBypass = true })
|
||||
end
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.shield_bash.onAutomatonAbilityCheck', function(target, automaton, skill)
|
||||
return 0
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Hammermill
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.shield_bash.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = automaton:getWeaponDmg()
|
||||
params.numHits = utils.clamp(1 + xi.automaton.getExtraHits(automaton, 1), 1, 8)
|
||||
params.fTP = { 1.0, 1.0, 1.0 }
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = params.numHits
|
||||
|
||||
local hammermillEquipped = automaton:hasAttachmentSet(xi.item.HAMMERMILL_ATTACHMENT)
|
||||
|
||||
if hammermillEquipped then
|
||||
local shieldBashBonus = 1.0 + automaton:getMod(xi.mod.SHIELD_BASH) / 100
|
||||
|
||||
params.fTP =
|
||||
{
|
||||
params.fTP[1] * shieldBashBonus,
|
||||
params.fTP[2] * shieldBashBonus,
|
||||
params.fTP[3] * shieldBashBonus,
|
||||
}
|
||||
end
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
|
||||
xi.mobskills.mobStatusEffectMove(automaton, target, xi.effect.STUN, 1, 0, 6)
|
||||
|
||||
if hammermillEquipped then
|
||||
applyHammermillSlow(automaton, target, skill, master)
|
||||
end
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Analyzer - Caps the amount of skills that can be analyzed to 1. https://wiki.ffo.jp/html/10746.html
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onEquip', function(pet, attachment)
|
||||
pet:setLocalVar('analyzedSkill1', 0)
|
||||
|
||||
pet:addListener('WEAPONSKILL_TAKE', 'ANALYZER_WEAPONSKILL_TAKE', function(mob, target, skill, tp, action)
|
||||
local analyzerModifier = target:getMod(xi.mod.AUTO_ANALYZER)
|
||||
local incomingSkill = skill:getID()
|
||||
|
||||
if analyzerModifier <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local analyzedSkill = target:getLocalVar('analyzedSkill1')
|
||||
|
||||
if incomingSkill == analyzedSkill then
|
||||
return
|
||||
end
|
||||
|
||||
if incomingSkill ~= analyzedSkill then
|
||||
target:setLocalVar('analyzedSkill1', incomingSkill)
|
||||
end
|
||||
end)
|
||||
|
||||
xi.automaton.onAttachmentEquip(pet, attachment)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onUnequip', function(pet, attachment)
|
||||
pet:setLocalVar('analyzedSkill1', 0)
|
||||
|
||||
pet:removeListener('ANALYZER_WEAPONSKILL_TAKE')
|
||||
|
||||
xi.automaton.onAttachmentUnequip(pet, attachment)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onManeuverGain', function(pet, attachment, maneuvers)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onManeuverLose', function(pet, attachment, maneuvers)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.attachments.analyzer.onUpdate', function(pet, attachment, maneuvers)
|
||||
end)
|
||||
|
||||
m:addOverride('utils.handleAutomatonAutoAnalyzer', function(actor, skill, damage)
|
||||
local analyzerModifier = actor:getMod(xi.mod.AUTO_ANALYZER)
|
||||
|
||||
if analyzerModifier <= 0 then
|
||||
return damage
|
||||
end
|
||||
|
||||
local automatonId = actor:getID()
|
||||
|
||||
if not automatonId then
|
||||
return damage
|
||||
end
|
||||
|
||||
local automatonMaster = actor:getMaster()
|
||||
|
||||
if not automatonMaster then
|
||||
return damage
|
||||
end
|
||||
|
||||
local incomingSkill = skill:getID()
|
||||
local analyzedSkill = actor:getLocalVar('analyzedSkill1')
|
||||
|
||||
if incomingSkill == analyzedSkill then
|
||||
local earthManeuvers = xi.automaton.getManeuverCount(automatonMaster, automatonMaster:countEffect(xi.effect.EARTH_MANEUVER))
|
||||
local damageReduction = 10 + 10 * earthManeuvers
|
||||
|
||||
return math.floor(damage * (100 - damageReduction) / 100)
|
||||
end
|
||||
|
||||
return damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Eraser - Changes Eraser to consume all Maneuvers on activation. https://wiki.ffo.jp/html/5365.html
|
||||
-----------------------------------
|
||||
local maneuvers =
|
||||
{
|
||||
xi.effect.FIRE_MANEUVER,
|
||||
xi.effect.ICE_MANEUVER,
|
||||
xi.effect.WIND_MANEUVER,
|
||||
xi.effect.EARTH_MANEUVER,
|
||||
xi.effect.THUNDER_MANEUVER,
|
||||
xi.effect.WATER_MANEUVER,
|
||||
xi.effect.LIGHT_MANEUVER,
|
||||
xi.effect.DARK_MANEUVER,
|
||||
}
|
||||
|
||||
local function removeAllManeuvers(master)
|
||||
-- Era Eraser consumes all active maneuvers, not just Light Maneuvers.
|
||||
for _, maneuverId in ipairs(maneuvers) do
|
||||
for _ = 1, master:countEffect(maneuverId) do
|
||||
master:delStatusEffectSilent(maneuverId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local removables =
|
||||
{
|
||||
-- Songs
|
||||
xi.effect.ELEGY,
|
||||
xi.effect.REQUIEM,
|
||||
xi.effect.THRENODY,
|
||||
|
||||
-- Enfeebling
|
||||
xi.effect.BLINDNESS,
|
||||
xi.effect.PARALYSIS,
|
||||
xi.effect.SILENCE,
|
||||
xi.effect.POISON,
|
||||
xi.effect.CURSE_I,
|
||||
xi.effect.CURSE_II,
|
||||
xi.effect.DISEASE,
|
||||
xi.effect.PLAGUE,
|
||||
xi.effect.WEIGHT,
|
||||
xi.effect.BIND,
|
||||
xi.effect.ADDLE,
|
||||
xi.effect.SLOW,
|
||||
xi.effect.PETRIFICATION,
|
||||
|
||||
-- DoTs
|
||||
xi.effect.BIO,
|
||||
xi.effect.DIA,
|
||||
xi.effect.BURN,
|
||||
xi.effect.FROST,
|
||||
xi.effect.CHOKE,
|
||||
xi.effect.RASP,
|
||||
xi.effect.SHOCK,
|
||||
xi.effect.DROWN,
|
||||
|
||||
-- Main Stat Downs
|
||||
xi.effect.STR_DOWN,
|
||||
xi.effect.DEX_DOWN,
|
||||
xi.effect.VIT_DOWN,
|
||||
xi.effect.AGI_DOWN,
|
||||
xi.effect.INT_DOWN,
|
||||
xi.effect.MND_DOWN,
|
||||
xi.effect.CHR_DOWN,
|
||||
|
||||
-- Combat Stat Downs
|
||||
xi.effect.ACCURACY_DOWN,
|
||||
xi.effect.ATTACK_DOWN,
|
||||
xi.effect.EVASION_DOWN,
|
||||
xi.effect.DEFENSE_DOWN,
|
||||
|
||||
-- Magic Stat Downs
|
||||
xi.effect.MAGIC_ACC_DOWN,
|
||||
xi.effect.MAGIC_ATK_DOWN,
|
||||
xi.effect.MAGIC_EVASION_DOWN,
|
||||
xi.effect.MAGIC_DEF_DOWN,
|
||||
|
||||
-- HP/MP/TP Stat Downs
|
||||
xi.effect.MAX_TP_DOWN,
|
||||
xi.effect.MAX_MP_DOWN,
|
||||
xi.effect.MAX_HP_DOWN,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.eraser.onAutomatonAbilityCheck', function(target, automaton, skill)
|
||||
return 0
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.eraser.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
automaton:addRecast(xi.recast.ABILITY, skill:getID(), 30)
|
||||
|
||||
local lightManeuvers = xi.automaton.getManeuverCount(master, master:countEffect(xi.effect.LIGHT_MANEUVER))
|
||||
local effectsRemoved = 0
|
||||
|
||||
for _, effectId in ipairs(removables) do
|
||||
if target:hasStatusEffect(effectId) then
|
||||
target:delStatusEffectSilent(effectId)
|
||||
effectsRemoved = effectsRemoved + 1
|
||||
|
||||
if effectsRemoved >= lightManeuvers then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
removeAllManeuvers(master)
|
||||
master:updateAttachments()
|
||||
|
||||
if effectsRemoved > 0 then
|
||||
skill:setMsg(xi.msg.basic.DISAPPEAR_NUM)
|
||||
else
|
||||
skill:setMsg(xi.msg.basic.USES)
|
||||
end
|
||||
|
||||
return effectsRemoved
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Economizer - Changes Economizer to consume all Dark Maneuvers on activation. : https://wiki.ffo.jp/html/10435.html
|
||||
-----------------------------------
|
||||
local activationThresholds =
|
||||
{
|
||||
[0] = 30,
|
||||
[1] = 40,
|
||||
[2] = 50,
|
||||
[3] = 60,
|
||||
}
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.economizer.onEquip', function(pet)
|
||||
pet:addListener('AUTOMATON_ATTACHMENT_CHECK', 'ATTACHMENT_ECONOMIZER', function(automaton, target)
|
||||
-- If Economizer is still on cooldown, do nothing.
|
||||
if automaton:hasRecast(xi.recast.ABILITY, xi.mobSkill.ECONOMIZER_AUTOMATON) then
|
||||
return
|
||||
end
|
||||
|
||||
local master = automaton:getMaster()
|
||||
|
||||
if not master then
|
||||
return
|
||||
end
|
||||
|
||||
local darkManeuvers = master:countEffect(xi.effect.DARK_MANEUVER)
|
||||
|
||||
if darkManeuvers == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local maxMP = automaton:getMaxMP()
|
||||
|
||||
-- If this automaton has no MP, do nothing.
|
||||
if maxMP == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local mpPercent = automaton:getMPP()
|
||||
local mpThreshold = activationThresholds[darkManeuvers] or 30
|
||||
|
||||
-- If the automaton's MP is above the threshold, do nothing.
|
||||
if mpPercent > mpThreshold then
|
||||
return
|
||||
end
|
||||
|
||||
automaton:useMobAbility(xi.mobSkill.ECONOMIZER_AUTOMATON, automaton)
|
||||
end)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.economizer.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
automaton:addRecast(xi.recast.ABILITY, skill:getID(), 180)
|
||||
|
||||
local darkManeuvers = master:countEffect(xi.effect.DARK_MANEUVER)
|
||||
local mpRecovered = math.floor(automaton:getMaxMP() * 0.2 * darkManeuvers)
|
||||
|
||||
for _ = 1, darkManeuvers do
|
||||
master:delStatusEffectSilent(xi.effect.DARK_MANEUVER)
|
||||
end
|
||||
|
||||
master:updateAttachments()
|
||||
|
||||
skill:setMsg(xi.msg.basic.SKILL_RECOVERS_MP)
|
||||
|
||||
return automaton:addMP(mpRecovered)
|
||||
end)
|
||||
|
||||
return m
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Reverts Hastega to no longer have a duration based on summoning magic and reduces haste power
|
||||
-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(04/08/2009)
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local moduleName = 'hastega'
|
||||
|
||||
if xi.module.isContentEnabled('WOTG') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
m:addOverride('xi.actions.abilities.pets.hastega.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
local duration = 180
|
||||
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
-- Reverts Garuda's Hastega to use 102/1024 or 9.96%
|
||||
local typeEffect = xi.effect.HASTE
|
||||
if target:addStatusEffect(typeEffect, { power = 996, duration = duration, origin = pet }) then
|
||||
if target:getID() == action:getPrimaryTargetID() then
|
||||
petskill:setMsg(xi.msg.basic.SKILL_GAIN_EFFECT_2)
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT)
|
||||
end
|
||||
else
|
||||
petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2)
|
||||
return
|
||||
end
|
||||
|
||||
return typeEffect
|
||||
end)
|
||||
|
||||
return m
|
||||
|
|
@ -1,838 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Date : 2016 November 10th Patch
|
||||
-- Notes: https://wiki.ffo.jp/html/35795.html
|
||||
-- Multihit skills' fTPs were lowered but the first hit fTP carried over into subsequent hits.
|
||||
-- In 75 era, the subsequent hits had a 1.0 multiplier.
|
||||
-- Old fTPs might be lost to time unless there new data is uncovered through online documentation or client data.
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
|
||||
local moduleName = 'rov_avatar_bloodpacts'
|
||||
|
||||
if xi.module.isContentEnabled('ROV') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
-----------------------------------
|
||||
-- Axe Kick
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.axe_kick.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Barracuda Dive
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.barracuda_dive.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Blindside
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.blindside.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
-- params.str_wSC = 0.20 -- TODO: Capture wSCs
|
||||
-- params.mnd_wSC = 0.20
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Burning Strike
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.burning_strike.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.75, 2.75, 2.75 }
|
||||
params.fTPSubsequentHits = { 2.75, 2.75, 2.75 }
|
||||
params.str_wSC = 0.20
|
||||
params.int_wSC = 0.20
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.hybridSkill = true
|
||||
params.hybridSkillElement = xi.element.FIRE
|
||||
params.hybridAttackType = xi.attackType.MAGICAL
|
||||
params.hybridDamageType = xi.damageType.FIRE
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
local totalDamage = 0
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
if info.damage > 0 then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
totalDamage = totalDamage + info.damage
|
||||
end
|
||||
|
||||
if info.hybridDamage > 0 and target:getHP() > 0 then
|
||||
target:takeDamage(info.hybridDamage, pet, info.hybridAttackType, info.hybridDamageType)
|
||||
totalDamage = totalDamage + info.hybridDamage
|
||||
end
|
||||
end
|
||||
|
||||
return totalDamage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Camisado
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.camisado.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.0, 2.0, 2.0 }
|
||||
params.fTPSubsequentHits = { 2.0, 2.0, 2.0 }
|
||||
params.str_wSC = 0.20
|
||||
params.mnd_wSC = 0.20
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
-- TODO: Knockback may not yet be hooked up to abilities.
|
||||
-- action:knockback(target:getID(), xi.action.knockback.LEVEL3)
|
||||
|
||||
-- TODO: Some equipment that reduces movement speed can reduce knockback distance. (Example: Plumb Boots)
|
||||
-- https://discord.com/channels/392903136336936960/883227978002206751/1280243231635804262
|
||||
-- https://discord.com/channels/443544205206355968/443893540922064896/1376405495845355661
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Chaotic Strike
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.chaotic_strike.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 3
|
||||
params.fTP = { 10.00, 10.00, 10.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.20
|
||||
params.int_wSC = 0.20
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_3
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.STUN, power = 1, duration = 12, origin = pet },
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Claw
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.claw.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.dex_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.PIERCING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Crag Throw
|
||||
-----------------------------------
|
||||
-- TODO: Not currently coded at time of this comment. Does not gain an accuracy bonus based on fTP.
|
||||
|
||||
-----------------------------------
|
||||
-- Crescent Fang
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.crescent_fang.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 1.50, 1.50, 1.50 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.PIERCING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.PARALYSIS, power = 22, duration = 60, origin = pet }, -- TODO: Capture power
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Double Punch
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.double_punch.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 2
|
||||
params.fTP = { 5.00, 5.00, 5.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_2
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Double Slap
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.double_slap.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 2
|
||||
params.fTP = { 6.328125, 6.328125, 6.328125 }
|
||||
params.fTPSubsequentHits = { 1.000000, 1.000000, 1.000000 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_2
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Eclipse Bite
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.eclipse_bite.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 3
|
||||
params.fTP = { 3.269531, 3.269531, 3.269531 }
|
||||
params.fTPSubsequentHits = { 1.000000, 1.000000, 1.000000 }
|
||||
params.dex_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_3
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Flaming Crush
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.flaming_crush.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 2
|
||||
params.fTP = { 6.00, 6.00, 6.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.20
|
||||
params.int_wSC = 0.20
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.hybridSkill = true
|
||||
params.hybridSkillElement = xi.element.FIRE
|
||||
params.hybridAttackType = xi.attackType.MAGICAL
|
||||
params.hybridDamageType = xi.damageType.FIRE
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_2
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
local totalDamage = 0
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
if info.damage > 0 then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
totalDamage = totalDamage + info.damage
|
||||
end
|
||||
|
||||
if info.hybridDamage > 0 and target:getHP() > 0 then
|
||||
target:takeDamage(info.hybridDamage, pet, info.hybridAttackType, info.hybridDamageType)
|
||||
totalDamage = totalDamage + info.hybridDamage
|
||||
end
|
||||
end
|
||||
|
||||
return totalDamage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Megalith Throw
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.megalith_throw.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getRangedDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.375, 2.375, 2.375 }
|
||||
params.fTPSubsequentHits = { 1.000, 1.000, 1.000 }
|
||||
params.str_wSC = 0.20
|
||||
params.agi_wSC = 0.20
|
||||
params.skipParry = true
|
||||
params.skipGuard = true
|
||||
params.skipBlock = true
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobRangedMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.SLOW, power = 3000, duration = 120, tier = 8, origin = pet }, -- TODO: Capture Slow tier
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Moonlit Charge
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.moonlit_charge.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 1.00, 1.00, 1.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.vit_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.BLINDNESS, power = 25, duration = 60, origin = pet },
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Mountain Buster
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.mountain_buster.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 7.25, 7.25, 7.25 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.vit_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobRangedMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Poison Nails
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.poison_nails.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.dex_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.PIERCING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.POISON, power = 1, tick = 3, duration = 90, tier = 1, origin = pet },
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Predator Claws
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.predator_claws.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 3
|
||||
params.fTP = { 10.00, 10.00, 10.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.dex_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_3
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Punch
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.punch.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Regal Gash
|
||||
-----------------------------------
|
||||
-- TODO: Not coded at time of this comment. Loses accuracy ftp scaling.
|
||||
|
||||
-----------------------------------
|
||||
-- Regal Scratch
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.regal_scratch.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
-- https://wiki.ffo.jp/html/26384.html
|
||||
-- JP Wiki states that this skill was excluded from carrying first hit fTP to subsequent hits.
|
||||
-- (See Patch note history for November 10th, 2016 in above link.)
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 3
|
||||
params.fTP = { 3.00, 3.00, 3.00 } -- TODO: Capture fTPs
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
-- params.dex_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_3
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Rock Buster
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.rock_buster.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.25, 2.25, 2.25 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.vit_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.BIND, power = 1, duration = 120, origin = pet }, -- TODO: Capture duration
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Rock Throw
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.rock_throw.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getRangedDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 1.00, 1.00, 1.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.20
|
||||
params.agi_wSC = 0.20
|
||||
params.skipParry = true
|
||||
params.skipGuard = true
|
||||
params.skipBlock = true
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobRangedMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.SLOW, power = 3000, duration = 120, tier = 8, origin = pet }, -- TODO: Capture Slow tier
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Rush
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.rush.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 5
|
||||
params.fTP = { 3.50, 3.50, 3.50 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_5
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Shock Strike
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.shock_strike.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.00, 2.00, 2.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.20
|
||||
params.int_wSC = 0.20
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.STUN, power = 1, duration = 12, origin = pet },
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Spinning Dive
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.spinning_dive.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 7.01171, 7.01171, 7.01171 }
|
||||
params.fTPSubsequentHits = { 1.00000, 1.00000, 1.00000 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Tail Whip
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.tail_whip.onPetAbility', function(target, pet, petskill, summoner, action)
|
||||
xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action)
|
||||
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = pet:getWeaponDmg()
|
||||
params.numHits = 1
|
||||
params.fTP = { 3.00, 3.00, 3.00 }
|
||||
params.fTPSubsequentHits = { 1.00, 1.00, 1.00 }
|
||||
params.str_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.attackMultiplier = { 2.0, 2.0, 2.0 }
|
||||
params.primaryMessage = xi.msg.basic.USES_JA_TAKE_DAMAGE
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(pet, target, petskill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(pet, target, petskill, action, info) then
|
||||
target:takeDamage(info.damage, pet, info.attackType, info.damageType)
|
||||
|
||||
local effectTable =
|
||||
{
|
||||
[1] = { effectId = xi.effect.WEIGHT, power = 50, duration = 120, tier = 1, origin = pet }, -- TODO: Capture power/duration/tier
|
||||
}
|
||||
|
||||
xi.combat.action.executeMobskillStatusEffect(pet, target, petskill, effectTable, { messageBypass = true })
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Volt Strike
|
||||
-----------------------------------
|
||||
-- TODO: Volt Strike is not currently coded at time of this comment but should be set to 1.0 for fTPSubsequentHits. Loses Crit Scaling.
|
||||
|
||||
return m
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Module: Spell Adjustments (Rhapsodies of Vana'diel Era)
|
||||
-- Desc: Reverts spell changes introduced during the RoV era
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local moduleName = 'rov_spell_adjustments'
|
||||
|
||||
if xi.module.isContentEnabled('ROV') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
-----------------------------------
|
||||
-- Enfeebling Magic
|
||||
-----------------------------------
|
||||
|
||||
-- Dia family: Revert defense down values.
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/55263-April.-3-2019-%28JST%29-Version-Update
|
||||
local function castEraDia(caster, target, spell, tier, dotPower, duration, defenseDown)
|
||||
local damage = xi.spells.damage.useDamageSpell(caster, target, spell)
|
||||
|
||||
-- Check for Bio.
|
||||
local bio = target:getStatusEffect(xi.effect.BIO)
|
||||
if
|
||||
not bio or
|
||||
(bio and bio:getTier() < tier)
|
||||
then
|
||||
target:delStatusEffect(xi.effect.BIO)
|
||||
local power = dotPower + caster:getMod(xi.mod.DIA_DOT)
|
||||
|
||||
target:addStatusEffect(xi.effect.DIA, { power = power, duration = duration, origin = caster, tick = 3, subPower = defenseDown, tier = tier })
|
||||
end
|
||||
|
||||
return damage
|
||||
end
|
||||
|
||||
m:addOverride('xi.actions.spells.white.dia.onSpellCast', function(caster, target, spell)
|
||||
return castEraDia(caster, target, spell, 1, 1, 60, 5)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.spells.white.dia_ii.onSpellCast', function(caster, target, spell)
|
||||
return castEraDia(caster, target, spell, 3, 2, 120, 10)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.spells.white.dia_iii.onSpellCast', function(caster, target, spell)
|
||||
return castEraDia(caster, target, spell, 5, 3, 180, 15)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.spells.white.diaga.onSpellCast', function(caster, target, spell)
|
||||
return castEraDia(caster, target, spell, 1, 1, 60, 5)
|
||||
end)
|
||||
|
||||
-- TODO: Blind II / Blind
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/46531-Mar-26-2015-%28JST%29-Version-Update
|
||||
-- - Remove fixed 180 duration, revert to between 80 and 300 seconds
|
||||
-- - Potency: Blind: (User INT - Opponent MND + 60)/4 Blind II: (User INT - Opponent MND + 100)/4
|
||||
|
||||
-- TODO: Paralyze / Paralyze II
|
||||
-- - Remove fixed 120 duration, revert to between 30 and 120 seconds
|
||||
|
||||
-- TODO: Poison / Poison II / Poisonga
|
||||
-- - Revert potencies to pre-RoV values
|
||||
|
||||
-----------------------------------
|
||||
-- Dark Magic
|
||||
-----------------------------------
|
||||
|
||||
-- Bio family: Revert attack down values.
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/55263-April.-3-2019-%28JST%29-Version-Update
|
||||
local function calculateBioPower(caster, tier)
|
||||
local skillLevel = caster:getSkillLevel(xi.skill.DARK_MAGIC)
|
||||
|
||||
if tier == 2 then
|
||||
return utils.clamp(math.ceil(skillLevel / 40), 1, 3)
|
||||
elseif tier == 4 then
|
||||
return utils.clamp(math.floor((skillLevel + 29) / 40), 3, 8)
|
||||
end
|
||||
|
||||
local power = 0
|
||||
if skillLevel > 291 then
|
||||
power = 13 + math.floor((skillLevel - 291) / 27) -- 13 + 1 every 27 skill levels.
|
||||
elseif skillLevel > 246 then
|
||||
power = 9 + math.floor((skillLevel - 246) / 11) -- 9 + 1 every 11 skill levels.
|
||||
else
|
||||
power = 5 + math.floor((skillLevel - 106) / 35) -- 5 + 1 every 35 skill levels.
|
||||
end
|
||||
|
||||
return utils.clamp(power, 5, 17)
|
||||
end
|
||||
|
||||
local function castEraBio(caster, target, spell, tier, duration, attackDown)
|
||||
local damage = xi.spells.damage.useDamageSpell(caster, target, spell)
|
||||
|
||||
-- Check for Dia.
|
||||
local dia = target:getStatusEffect(xi.effect.DIA)
|
||||
if
|
||||
not dia or
|
||||
(dia and dia:getTier() < tier)
|
||||
then
|
||||
target:delStatusEffect(xi.effect.DIA)
|
||||
local power = calculateBioPower(caster, tier)
|
||||
|
||||
target:addStatusEffect(xi.effect.BIO, { power = power, duration = duration, origin = caster, tick = 3, subPower = attackDown, tier = tier })
|
||||
end
|
||||
|
||||
return damage
|
||||
end
|
||||
|
||||
m:addOverride('xi.actions.spells.black.bio.onSpellCast', function(caster, target, spell)
|
||||
return castEraBio(caster, target, spell, 2, 60, 5)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.spells.black.bio_ii.onSpellCast', function(caster, target, spell)
|
||||
return castEraBio(caster, target, spell, 4, 120, 10)
|
||||
end)
|
||||
|
||||
m:addOverride('xi.actions.spells.black.bio_iii.onSpellCast', function(caster, target, spell)
|
||||
return castEraBio(caster, target, spell, 6, 180, 15)
|
||||
end)
|
||||
|
||||
-- Dread Spikes: Revert duration from 3 minutes to 1 minute.
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/48564-Sep-16-2015-%28JST%29-Version-Update
|
||||
m:addOverride('xi.effects.dread_spikes.onEffectGain', function(target, effect)
|
||||
super(target, effect)
|
||||
effect:setDuration(60000)
|
||||
end)
|
||||
|
||||
-- TODO Absorb-STAT: Add decay tick and set 90 second duration to boost effects
|
||||
-- TODO Drain II: Set duration of max HP boost to 60 seconds.
|
||||
-- Source:
|
||||
-- Decay Removal: http://forum.square-enix.com/ffxi/threads/46531-Mar-26-2015-%28JST%29-Version-Update
|
||||
-- Duration Change: https://forum.square-enix.com/ffxi/threads/48564-Sep-16-2015-%28JST%29-Version-Update
|
||||
|
||||
-----------------------------------
|
||||
-- Singing
|
||||
-----------------------------------
|
||||
|
||||
-- TODO (pending exposure of pTables in magic scripts):
|
||||
-- Update scripts/globals/spells/enhancing_song.lua pTable entries:
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/55899-September.-10-2019-%28JST%29-Version-Update?p=619588&viewfull=1#post619588
|
||||
-- xi.magic.spell.FOE_SIRVENTE : MERIT_ID 0 -> xi.merit.FOE_SIRVENTE, POWER_BASE 35 -> 0
|
||||
-- xi.magic.spell.ADVENTURERS_DIRGE : MERIT_ID 0 -> xi.merit.ADVENTURERS_DIRGE, POWER_BASE 32 -> 5
|
||||
|
||||
-- POWER_CAP value: current -> target:
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/52095-Feb.-10-2017-%28JST%29-Version-Update
|
||||
-- xi.magic.spell.FIRE_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.ICE_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.WIND_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.EARTH_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.LIGHTNING_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.WATER_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.LIGHT_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.DARK_CAROL : POWER_CAP 80 -> 50, MULTIPLIER 8 -> 5
|
||||
-- xi.magic.spell.SWORD_MADRIGAL : POWER_CAP 45 -> 15, MULTIPLIER 4.5 -> 2, DIVISOR 18 -> 23.25, SKILL_REQUIREMENT 85 -> 40
|
||||
-- xi.magic.spell.BLADE_MADRIGAL : POWER_CAP 60 -> 30, MULTIPLIER 6 -> 2
|
||||
-- xi.magic.spell.SHEEPFOE_MAMBO : POWER_CAP 48 -> 15, MULTIPLIER 5 -> 2.5
|
||||
-- xi.magic.spell.DRAGONFOE_MAMBO : POWER_CAP 72 -> 23, MULTIPLIER 7 -> 2.5
|
||||
-- xi.magic.spell.ADVANCING_MARCH : POWER_CAP 108 -> 64, MULTIPLIER 11 -> 16
|
||||
-- xi.magic.spell.VICTORY_MARCH : POWER_CAP 163 -> 96, POWER_BASE 43 -> 53
|
||||
-- xi.magic.spell.KNIGHTS_MINNE : POWER_CAP 30 -> 13, MULTIPLIER 3 -> 2.5, DIVISOR 10 -> 15, POWER_BASE 8 -> 5
|
||||
-- xi.magic.spell.KNIGHTS_MINNE_II : POWER_CAP 69 -> 27, MULTIPLIER 7 -> 2.5, DIVISOR 10 -> 15, POWER_BASE 12 -> 6
|
||||
-- xi.magic.spell.KNIGHTS_MINNE_III: POWER_CAP 108 -> 40, MULTIPLIER 11 -> 2.5, DIVISOR 10 -> 15, POWER_BASE 18 -> 10
|
||||
-- xi.magic.spell.KNIGHTS_MINNE_IV : POWER_CAP 164 -> 48, MULTIPLIER 16 -> 2.5, DIVISOR 10 -> 15, POWER_BASE 30 -> 12
|
||||
-- xi.magic.spell.VALOR_MINUET : POWER_CAP 30 -> 16, MULTIPLIER 3 -> 2.5, DIVISOR 4.3 -> 6
|
||||
-- xi.magic.spell.VALOR_MINUET_II : POWER_CAP 69 -> 32, MULTIPLIER 6 -> 2.5, DIVISOR 3.9 -> 6, SKILL_REQUIREMENT 100 -> 85
|
||||
-- xi.magic.spell.VALOR_MINUET_III : POWER_CAP 108 -> 48, MULTIPLIER 9 -> 2.5, DIVISOR 3.5 -> 6
|
||||
-- xi.magic.spell.VALOR_MINUET_IV : POWER_CAP 164 -> 56, MULTIPLIER 11 -> 2.5, DIVISOR 3.3 -> 15, POWER_BASE 31 -> 29
|
||||
-- xi.magic.spell.HUNTERS_PRELUDE : POWER_CAP 45 -> 15, MULTIPLIER 4.5 -> 2
|
||||
-- xi.magic.spell.ARCHERS_PRELUDE : POWER_CAP 60 -> 30, MULTIPLIER 6 -> 2
|
||||
|
||||
-----------------------------------
|
||||
-- Ninjutsu
|
||||
-----------------------------------
|
||||
|
||||
-- San Spells: Add +5 Magic Attack and +5 Magic Accuracy per merit rank
|
||||
-- Source: https://forum.square-enix.com/ffxi/threads/55525-June.-10-2019-%28JST%29-Version-Update
|
||||
local sanSpellOverrides =
|
||||
{
|
||||
{ path = 'xi.actions.spells.ninjutsu.katon_san.onSpellCast', merit = xi.merit.KATON_SAN },
|
||||
{ path = 'xi.actions.spells.ninjutsu.hyoton_san.onSpellCast', merit = xi.merit.HYOTON_SAN },
|
||||
{ path = 'xi.actions.spells.ninjutsu.huton_san.onSpellCast', merit = xi.merit.HUTON_SAN },
|
||||
{ path = 'xi.actions.spells.ninjutsu.doton_san.onSpellCast', merit = xi.merit.DOTON_SAN },
|
||||
{ path = 'xi.actions.spells.ninjutsu.raiton_san.onSpellCast', merit = xi.merit.RAITON_SAN },
|
||||
{ path = 'xi.actions.spells.ninjutsu.suiton_san.onSpellCast', merit = xi.merit.SUITON_SAN },
|
||||
}
|
||||
|
||||
for _, entry in ipairs(sanSpellOverrides) do
|
||||
m:addOverride(entry.path, function(caster, target, spell)
|
||||
local meritBonus = caster:getMerit(entry.merit)
|
||||
caster:addMod(xi.mod.MATT, meritBonus)
|
||||
caster:addMod(xi.mod.MACC, meritBonus)
|
||||
|
||||
local damage = super(caster, target, spell)
|
||||
|
||||
caster:delMod(xi.mod.MATT, meritBonus)
|
||||
caster:delMod(xi.mod.MACC, meritBonus)
|
||||
|
||||
return damage
|
||||
end)
|
||||
end
|
||||
|
||||
return m
|
||||
|
|
@ -1,305 +0,0 @@
|
|||
-----------------------------------
|
||||
-- WoTG Era Automaton Weaponskills
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local moduleName = 'wotg_automaton'
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
if xi.module.isContentEnabled('ABYSSEA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
-----------------------------------
|
||||
-- Arcuballista
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.arcuballista.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = xi.automaton.getRangedBaseDamage(automaton)
|
||||
params.numHits = 1
|
||||
params.fTP = { 2.5, 3.0, 4.0 }
|
||||
params.dex_wSC = 0.30
|
||||
params.accuracyModifier = { 100, 100, 100 }
|
||||
params.attackType = xi.attackType.RANGED
|
||||
params.damageType = xi.damageType.PIERCING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.skipParry = true
|
||||
params.skipGuard = true
|
||||
params.skipBlock = true
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Armor Piercer
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.armor_piercer.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = xi.automaton.getRangedBaseDamage(automaton)
|
||||
params.numHits = 1
|
||||
params.fTP = { 3.0, 3.5, 4.0 }
|
||||
params.dex_wSC = 0.30
|
||||
params.ignoreDefense = { 0.5, 0.5, 0.5 }
|
||||
params.accuracyModifier = { 100, 100, 100 }
|
||||
params.attackType = xi.attackType.RANGED
|
||||
params.damageType = xi.damageType.PIERCING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.skipParry = true
|
||||
params.skipGuard = true
|
||||
params.skipBlock = true
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Bone Crusher
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.bone_crusher.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = automaton:getWeaponDmg()
|
||||
params.numHits = utils.clamp(3 + xi.automaton.getExtraHits(automaton, 3), 1, 8)
|
||||
params.fTP = { 1.5, 1.5, 1.5 }
|
||||
params.vit_wSC = 0.30
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = params.numHits
|
||||
|
||||
if target:isUndead() then
|
||||
params.fTP = { 2.5, 2.5, 2.5 }
|
||||
end
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
|
||||
xi.mobskills.mobStatusEffectMove(automaton, target, xi.effect.STUN, 1, 0, 4)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Cannibal Blade
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.cannibal_blade.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = automaton:getSkillLevel(xi.skill.AUTOMATON_MELEE) / 9.2
|
||||
params.numHits = 1
|
||||
params.fTP = { 11.0, 12.5, 14.0 }
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.guaranteedFirstHit = true
|
||||
params.skipFSTR = true
|
||||
params.skipPDIF = true
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
|
||||
if not target:isUndead() then
|
||||
automaton:addHP(info.damage)
|
||||
end
|
||||
end
|
||||
|
||||
-- Does not return TP.
|
||||
automaton:setTP(0)
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Chimera Ripper
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.chimera_ripper.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = automaton:getWeaponDmg()
|
||||
params.numHits = utils.clamp(1 + xi.automaton.getExtraHits(automaton, 1), 1, 8)
|
||||
params.fTP = { 2.0, 2.5, 3.0 }
|
||||
params.str_wSC = 0.30
|
||||
params.accuracyModifier = { 100, 100, 100 }
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = params.numHits
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Daze
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.daze.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = xi.automaton.getRangedBaseDamage(automaton)
|
||||
params.numHits = 1
|
||||
params.fTP = { 5.0, 5.5, 6.0 }
|
||||
params.dex_wSC = 0.30
|
||||
params.accuracyModifier = { 150, 150, 150 }
|
||||
params.attackType = xi.attackType.RANGED
|
||||
params.damageType = xi.damageType.PIERCING
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
|
||||
params.skipParry = true
|
||||
params.skipGuard = true
|
||||
params.skipBlock = true
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
|
||||
xi.mobskills.mobStatusEffectMove(automaton, target, xi.effect.STUN, 1, 0, 4)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Knockout
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.knockout.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.numHits = utils.clamp(1 + xi.automaton.getExtraHits(automaton, 1), 1, 8)
|
||||
params.fTP = { 4.0, 4.5, 5.0 }
|
||||
params.agi_wSC = 0.40
|
||||
params.accuracyModifier = { 50, 50, 50 }
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = params.numHits
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
|
||||
xi.mobskills.mobStatusEffectMove(automaton, target, xi.effect.EVASION_DOWN, 20, 0, 30)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Magic Mortar
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.magic_mortar.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = automaton:getMaxHP() - automaton:getHP()
|
||||
params.fTP = { 0.50, 0.75, 1.00 }
|
||||
params.element = xi.element.NONE
|
||||
params.attackType = xi.attackType.MAGICAL
|
||||
params.damageType = xi.damageType.ELEMENTAL
|
||||
params.shadowBehavior = xi.mobskills.shadowBehavior.IGNORE_SHADOWS
|
||||
|
||||
-- Flame Holder multiplies the base damage of Magic Mortar. Gives a 25% boost at 3 Fire Maneuvers.
|
||||
local flameHolderModifier = 1.0 + (automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) - 100) / 1000
|
||||
|
||||
if flameHolderModifier > 1.0 then
|
||||
params.baseDamage = math.floor(params.baseDamage * flameHolderModifier)
|
||||
end
|
||||
|
||||
local info = xi.mobskills.mobMagicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- Slapstick
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.slapstick.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.numHits = utils.clamp(3 + xi.automaton.getExtraHits(automaton, 3), 1, 8)
|
||||
params.fTP = { 1.0, 1.0, 1.0 }
|
||||
params.str_wSC = 0.20
|
||||
params.dex_wSC = 0.20
|
||||
params.accuracyModifier = { 0, 30, 50 }
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.BLUNT
|
||||
params.shadowBehavior = params.numHits
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
-----------------------------------
|
||||
-- String Clipper
|
||||
-----------------------------------
|
||||
m:addOverride('xi.actions.abilities.pets.automaton.string_clipper.onAutomatonAbility', function(target, automaton, skill, master, action)
|
||||
local params = {}
|
||||
|
||||
params.baseDamage = automaton:getWeaponDmg()
|
||||
params.numHits = utils.clamp(2 + xi.automaton.getExtraHits(automaton, 2), 1, 8)
|
||||
params.fTP = { 2.0, 2.0, 2.0 }
|
||||
params.str_wSC = 0.15
|
||||
params.dex_wSC = 0.15
|
||||
params.attackMultiplier = { 1.5, 1.5, 1.5 }
|
||||
params.accuracyModifier = { 0, 50, 100 }
|
||||
params.attackType = xi.attackType.PHYSICAL
|
||||
params.damageType = xi.damageType.SLASHING
|
||||
params.shadowBehavior = params.numHits
|
||||
|
||||
xi.automaton.applyFlameHolder(automaton, params.fTP)
|
||||
|
||||
local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params)
|
||||
|
||||
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
|
||||
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
|
||||
end
|
||||
|
||||
return info.damage
|
||||
end)
|
||||
|
||||
return m
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
-----------------------------------
|
||||
-- Pre-SoA Magic Burst Module
|
||||
-- Restores the pre-2015 magic burst multiplier: 1.25 + 0.05 per skillchain step.
|
||||
-- https://forum.square-enix.com/ffxi/threads/46531
|
||||
-----------------------------------
|
||||
require('modules/module_utils')
|
||||
-----------------------------------
|
||||
local moduleName = 'era_magic_burst'
|
||||
|
||||
if xi.module.isContentEnabled('SOA') then
|
||||
return { name = moduleName }
|
||||
end
|
||||
|
||||
local m = Module:new(moduleName)
|
||||
|
||||
m:addOverride('xi.spells.damage.calculateIfMagicBurst', function(caster, target, spellElement, magicBurstTier)
|
||||
if spellElement <= xi.element.NONE then
|
||||
return 1
|
||||
end
|
||||
|
||||
return 1.25 + 0.05 * utils.clamp(magicBurstTier, 1, 5)
|
||||
end)
|
||||
|
||||
return m
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue